Клуб API Карт

Cluster Balloon AJAX

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

Помогите пож.

На карте есть метки. При ините меток полям свойств балуна задаются только начальные значения.

Часть примера:

my_geo_mt[i_mt] = new ymaps.GeoObject({
                                        // Описываем геометрию типа "Точка".
                                        geometry: {type: "Point",coordinates: [mt_x, mt_y]},
                                        // Описываем данные геообъекта.
                                        properties: {
                                            hintContent: "MT "+ mt_id,
                                            balloonContentHeader: '<div><h5 align="center">MT '+ mt_id +'</h5></div>',
                                            balloonContentBody: '<div id="mt_id_'+ mt_id +'" ><h5>загружаемся</h5></div>',

Далее значения полей подгружаются по открытию Балуна на метке. Переписывая начальные данные.

Все как бы и хорошо , только когда метки собираются в кластер. Там есть свой балун. Который автоматически агрегирует балуны меток, входящих в него. Только там отображаются данные, которые были начальными на метке при ее инициализации. А ajax обработчик сюда  уже не загружает обновленные данные (он работает только по событию при клике (balloonopen) на метках, когда они не собраны в икону кластера ).

Как можно обновить данные в балуне кластера (при списке меток). Может тут событие как-то можно отловить например при смене маркера активной метки в балуне кластера и написать другой обработчик события или как-то этот же использовать ??

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

var currentCluster = null,

     stateListener = null,

     activeObject = null;

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

     currentCluster = e.get('target');

     activeObject = currentCluster.state.get('activeObject');

     // тут наверное подгрузка данных...

     // когда данные загрузились и записались, вызываем

     currentCluster.balloon.getOverlay().getLayout().rebuild();

     stateListener = currentCluster.state.events.group();

    stateListener.add('change', function () {

        if (currentCluster.state.get('activeObject') != activeObject) {

                // и тут наверное подгрузка данных...

               // когда данные загрузились и записались, вызываем

               currentCluster.balloon.getOverlay().getLayout().rebuild();

               activeObject = currentCluster.state.get('activeObject');

        }

     });

 });

clusterer.events.add('balloonclose', function () {

     stateListener.removeAll();

     stateListener = null;

     activeObject = null;

     currentCluster = null;

 });

 

Пока что так. В будущих релизах появится автоматическое перестроение балуна при изменении данных.

Удалённый пользователь
28 января 2016, 03:48

Спасибо. Попробую разобраться.

 

>>Пока что так. В будущих релизах появится автоматическое перестроение балуна при изменении данных.

 

Да было бы не плохо. Чтобы балун кластера мог не  быть отдельным объектом со своим механизмом, а состоял из балунов меток, их обработчиков и т д. Просто бы к ним вывод дописать как надстройку, которая подключается автоматически при инициализации и сборе в кластер.

Удалённый пользователь
28 января 2016, 03:48

О а еще можно вопрос?

Допустим получились данные ajax - ом. А куда их потом писать?

Для метки раньше они писались вот так :

ajaxObj.conteinerID.properties.set('balloonContentBody', ajaxObj.responseText);

 

А для кластера как писать? Или также оно сработает?

Если так записать то не вот эта строчка все перечитывает?

 currentCluster.balloon.getOverlay().getLayout().rebuild();

Удалённый пользователь
28 января 2016, 03:48

А вот это надо запускать в callBack функци ajax ?

currentCluster.balloon.getOverlay().getLayout().rebuild();

TypeError: currentCluster.balloon.getOverlay is not a function

А это оно так ругается.

И правда нет такого метода, я вас обманула. Мы пойдем другим путем!

 

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

http://clubs.ya.ru/mapsapi/29156/29346#reply-mapsapi-29346

 

При таком макете не нужно будет руками вызывать метод rebuild, он будет сам перестраиваться.

Удалённый пользователь
28 января 2016, 03:48

Спасибо. Сейчас попробую разобраться.

Удалённый пользователь
28 января 2016, 03:48

Сделал спасибо заработало. Только вытягивает данные тольо для той метки для которой ранее аяксом были подгружены данные. Остальные метки выводит не подгруженные. Нельзя ли как-то в MyMainContentLayout или MyMainContentSubLayout  (не разобрался пока где точно надо сделать инициализацию AJAX запроса, но подозреваю, что где-то сдесь -- в одном из двух мест). В идеале бы инициализировать AJAX запрос для меток по активному объекту внутри балуна кластера. Не подскажете где этот  запрос можно вставлять?

 

Или может не запрос а как-то бросить событие из балуна кластера на открытие балуна нужной метки, а оно обработчиком метки и подтянет данные ? Чтобы не городить двойной огород запросов (1- в кластере  2- в самой метке)? Может как-то так можно?

Можно внутри функции applyContent делать запрос за данными для нужной метки. Когда данные придут, их надо записать в поля, который использует MyMainContentSubLayout, и он автоматом перестроится.

Удалённый пользователь
28 января 2016, 03:48

applyContent: function () {
                            // Для того, чтобы макет автоматически изменялся при обновлении данных
                            // в геообъекте, создадим дочерний макет через фабрику
                            var subLayout = new MyMainContentSubLayout({
                                    options: this.options,
                                    properties: this.activeObject.properties
                                });
                            // прицепим новый макет к родителю
                            subLayout.setParentElement(this.getParentElement());
                        }
                    });

 

 

В этой функции как лучше всего получить активный объект?  (в смысле метку)  С нее ид просто надо снять для того чтобы сделать запрос за конкретными данными.  И еще как можно записать данные после получения? Раньше в метку  писал вот так :

ajaxObj.conteinerID.properties.set('description', ajaxObj.responseText);

 

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

 

В классе макета есть поле this.activeObject - это и есть ссылка на метку. Писать данные this.activeObject.properties.set(....)

Удалённый пользователь
28 января 2016, 03:48

Спасибо

Удалённый пользователь
28 января 2016, 03:48

Заработало. Еще раз спасибо

Отлично)