Клуб API Карт

изменение контента балуна кластера

Пост в архиве.

Доброго времени суток. Может быть кто знает, как изменять содержимое балуна кластера при клике на элемент sidebar'a слева?

27 комментариев

В последней версии была реализована функция автообновления правой части балуна. То есть вам нужно по клику обновлять соответствующие поля данных у геообъекта, и правая часть сама перестроится.

А если используется собственный макет для балуна кластера(для правой его части)?

т.е. я определил свой clusterBalloonMainContentLayout у кластера, в макете в build заполняю содержимое балуна взависимости от активной метки в кластере. При клике слева на список объектов кластера функция buid не вызывается.

Как перестраивать содержимое балуна? 

Вы можете записывать данные для метки в ее properties. В момент изменения значения этого поля произойдет событие 'change'. Вы можете слушать это событие на properties метки в макете clusterBalloonMainContentLayout и обновлять содержимое правой части. 

а почему не срабатывает buid у clusterBalloonMainContentLayout по клику по меткам в левой части? нужно перестраивать правую часть самому? ок, как отследить клик по меткам слева?

Как все происходит в стандартном балуне.

При клике на пункте из списка у кластера обновляется значение поля cluster.state.get('activeObject'). Правая часть балуна ловит событие change на поле state кластера и обновляет содержимое. Также слушаются изменения на поле properties активной метки (выбранной в текущий момент), чтобы балун перестраивался при изменении данных метки.

Если вы пишете свой макет, то вам нужно будет реализовать какую-то часть из вышеописанной логики по аналогии со стандартным балуном кластера. 

я не могу определить актианый объект sidebar'a

у меня build собственного макета след вида 

{

this.constructor.superclass.build.call(this);

var activeObject = this.getData().state.get("activeObject");

}

 

скрипт ругается что state не определён, в чём может быть дело?

 

В макет элемента списка передается модифицированный набор данных, чтобы удобнее было работать. Попробуйте обратиться так

this.getData().data.get('geoObject')

Марина, спасибо
есть еще вопрос, допустим я создал clusterer, добавил в него объекты, добавил на карту
var clusterer = new ymaps.Clusterer({});
clusterer.add(myGeoObjects);
map.geoObjects.add(clusterer);
Как подписаться на событие change?
такой способ не проходит
clusterer.state.events.add('change', function () {
                alert('change');
            });
а в buid получается
this.getData().state.events.add('change', function () {
                            alert('change');
                        });
т.е. это можно делать только в buid'e?

А за какими именно изменениями вы хотите следить? Событие change генерируют очень многие сущности. 

Если вы хотите следить за activeObject, то нужно слушать событие на менеджере состояния кластера.

clusterer.events.add('balloonopen', function (e) {

    var cluster = e.get('target');

    cluster.state.events.add('change', function () {.....});

});

 

Соответственно слушателя надо снимать когда приходит событие balloonclose

фигня какаято, не работает

clusterer.events.add('balloonopen', function (e) {
e.get('target').state.events.add('change', function () {
console.log('change');
});
});
clusterer.events.add('balloonclose', function (e) {
e.get('target').state.events.remove('change', function (e) { alert("remove"); });
});

alert не выводится, соответственно на каждое открытие балуна навешивается функция 

Этот change выведется после того, как изменится активный объект при открытом балуне. У вас  происходит смена объекта?

Ок, суммирую

var myClusterBalloonLayout = ymaps.templateLayoutFactory.createClass(
"" +
"

" +
"", {
build: function () {
    var parent = this.getParentElement();
    parent.innerHTML = 'тест';
}
});
clusterer = new ymaps.Clusterer({clusterBalloonMainContentLayout: myClusterBalloonLayout }); 

//вешаю событие на открытие кластера 

clusterer.events.add('balloonopen', onClusterOpen);

function onClusterOpen(e) {
   e.get('target').state.events.remove('change');
   e.get('target').state.events.add('change', onStateChange);

//клик по меткам слева 

function onStateChange(e) {
   var state = e.get('target');
   var active = e.get('target').get('activeObject');

итак, в функции  onStateChange  нужно вызвать метод buid макета балуна(т.е. перестроить его содержимое), который я определил ранее. Как я могу это сделать? 

 

Вам стоит сделать так - внутри функции build начать слушать событие change на  state

build: function () {

   myClusterBalloonLayout.superclass.build.call(this);

    this.activeObject = this.getData().state.get('activeObject');

    this.getData().state.events.add('change', onStateChange, this);

}

clear: function () {

    this.getData().state.events.remove('change'. onStateChange, this);

    myClusterBalloonLayout.superclass.clear.call(this);

}

 

....

 

function onStateChange () {

    if (this.activeObject != this.getData().state.get('activeObject')) {

       this.activeObject = this.getData().state.get('activeObject');

      // тут обновление контента балуна

    }

}

 

то, что нужно!

такие примеры очень бы не помешали в руководстве

Спасибо! 

Пример на кастомизацию балуна почти готов и ждет своего зведного часа :)

Сделал все как описано на http://api.yandex.ru/maps/jsbox/cluster_balloon_layout

Все корректно показывается, но почему-то не происходит события смены элемента слева, подскажите куда смотреть нужно. Версия API 2.0-Stable

 

В версии 2.0.18 логика построения балуна кластера была немного изменена в пользу удобной кастомизации макета. Поэтому пример из песочницы не работает на версии 2.0-stable. Пример работает в версиях, начиная с 2.0.18 и старше.

Заработало, правда наблюдается странность. Вместо того чтобы затирать справа, он новый контент добавляет снизу ... подскажите куда посмотреть можно, чтобы понять в чем дело ?

Вы не могли бы дать ссылку или привести код?

Владимир Б.
28 января 2016, 03:23

тоже волнует вопрос, как сделать что бы не добавлялось ниже, а обновлялось содержание справа.

взял ваш пример из другой ветки http://site-do.ru/burdiyan/xmlplusclasster.html

 

Мы недавно обновили пример в песочнице, чтобы эта проблема не возникала. Посмотрите, как обнуляется предыдущий контент в функции applyContent http://api.yandex.ru/maps/jsbox/cluster_balloon_layout

Владимир Б.
28 января 2016, 03:23

спасибо! то что нужно!

Владимир Б.
28 января 2016, 03:23

возникла новая задача. может быть вы поможете и в её решении?

необходимо, что бы при переходе по ссылке вида mysite.ru#id123 открывался балун метки с данным id.

детали получения номера из url меня не интересуют, а суть вопроса сводится к следующему:

предположим, на странице в js задана переменная $id, содержащая число

на карту выводятся метки из xml, каждая метка имеет property.id

как открыть балун метки с номером id = $id при загрузке страницы?

Нужно каким-то образом найти объект, у которого выставлено это id (например перебрать просто массив, который добавляли в кластеризатор).

А потом, имея ссылку на объект, можно открыть балун кластера или метки как в примере из документации http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/Clusterer.xml (пример №2).

Владимир Б.
28 января 2016, 03:23

спасибо. пробую так

var item=10;

res.geoObjects.each(function (geoObject) {
    if (geoObject.properties.get('id')==item){
        openGeo=geoObject;
    }

}

openGeo.balloon.open();

 

похоже так нельзя присваивать объекты?

Владимир Б.
28 января 2016, 03:23

вопрос закрыт. код работает

под каждую возникающую задачу лучше создавать отдельный пост в клубе