Клуб 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;

 });

 

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

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

 

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

 

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

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

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

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

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

 

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

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

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

А вот это надо запускать в 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, он будет сам перестраиваться.

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

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

 

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

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

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(....)

Спасибо

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

Отлично)