Клуб API Карт

API 2.0, Placemark - показать принудительно Balloon

ultranton
27 мая 2012, 01:54

День добрый. Начинаю потихоньку разбираться с API 2.0.

Возникла небольшая проблема. Я создаю кучу placemark'еров на карте такого вида:

mark = new ymaps.Placemark (

                            [30.30,40.40], {

                                hintContent: 'hint',

                                balloonContent: 'balloon'

                            } , {

                                iconImageHref: '/images/blub.png',

                                iconImageSize: [36,41],

                                iconImageOffset: [-13,-40]

                            }

 

Потом я сохраняю ссылку на mark в глобальном хэш-массиве (объекте), где ключ - это уникальный id этого placemark'а в пределах всей карты:

board_by_id = {};

board_by_id[666] = mark;

 

Что характерно, координаты я получаю нормально:

var current_mark = board_by_id[666];

var coords = current_mark.geometry.getCoordinates(

 

Но не могу заставить показаться Balloon у того же объекта current_mark.

11 комментариев
Подписаться на комментарии к посту

А как вы пытаетесь заставить показаться балун?

Пытался так:

current_mark.openBalloon();

current_mark.balloon.open();

Вот код, который у меня отрабатывает как надо.

var placemark = new ymaps.Placemark([35, 35], {balloonContent: 'balloon'});

map.geoObjects.add(placemark);

placemark.balloon.open();

 

ну так и у меня работает =)

задача открыть balloon у одного из многих ранее созданных placemark'ов

 

Я изначально делал кучу placemark'ов в группы объединённые в Clusterer. Balloon не открывается, даже когда уже самого значка кластера нет и марки все видны на карте. Потом тупо "в лоб" сделал, накидав марков на карту - тоже самое. И что характерно - координаты-то нормально берутся из хэш-массива. И координаты-то верные =)

 

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

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

проект внутренний :\

вот примерный код целиком: http://pastebin.com/jP5BLYgw

 

Сначала создаётся массив в javascript; создаётся карта; создаются на ней кластеры согласно данным из массива, при создании кластера созданные placemark'и сохраняются в глобальном хэш-массиве (id из массива : объект Placemark); создаётся меню (собсно, по клику в котором, и вызывается функция "полёта" flyTo).

 

В теле функции flyTo нужно вызвать balloon нужного placemark'а.

Подозрение большое, что что-то не так с "видимостью" переменных.

Сложно что-то сказать по этому коду. На вид все должно быть ок. В теле функции flyTo идет обращение к метке - поэтому никаких проблем с областью видимости быть не должно. Единственное, что я могу предположить - это что у вас метка в момент открытия балуна не добавлена на карту. 

У вас метки добавляются в кластеризатор - это далеко не означает, что сама метка находится на карте - она может быть внутри кластера, может быть вне видимости карты. Поэтому балун и не откроется.

Я почти победил эту зверюгу) Забыл, что panTo работает в отдельном потоке. Решилось добавлением callback-функции в panTo в функции flyTo:

function flyTo(board_id) {

var mark = board_by_id[board_id];

var coords = mark.geometry.getCoordinates();

map.setZoom(12);

map.panTo(coords, {callback: (function(){mark.balloon.open();})

});

}

 

Однако теперь проблема. Если мы сначала открыли балун у одной точки, а потом у другой, лежащей вне видимости, то переход происходит, а показ балуна нет - только при повторном вызове. Т.е. если pan идёт до точки вне карты, то callback-функция не вызывается :(

Кстати, гарантия видимости метки - это как раз ограничение действия кластеризатора на уровень zoom'а в 6, тогда как метки показываются на уровне 12. Ну и плюс pan всей карты до её координат.

По идее происходит так - 

1. Срабатывает panTo до точки за пределами карты

2. Вызывается колбек на открытие балуна

3. Кластеризатор детектит, что карта сдвинулась

4. Добавляет новые метки на карту.

 

Как видите, команда на открытие балуна приходит до того, как точка фактически добавляется на карту.

Можно попробовать модифицировать код так

...

map.panTo(coords, {callback: function() {

    if (mark.getMap()) {

       mark.balloon.open();

    } else {

       var markListener = mark.events.group()

           .add('mapchange', function(e) {

               // как только метка добавится на карту, откроем балун и снимем слушателя

                if (e.get('newMap')) {

                    mark.balloon.open();

                    markListener.removeAll();

                }

            });

    }

}})

...

спасибо огромное! работает =)