Клуб API Карт

API v2 - темплейт балуна и метка кластеризатора

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

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

В примерах есть только вариант с картинкой. Но мне нужен полноценный, чтобы можно было выводить атрибуты метки (name, description etc)

 

А еще столкнулся с такой проблемой: для кнопки закрытия пробую задавать опцию balloonCloseButtonLayout. Внешний вид кнопки меняется, но она перестает реагировать на клик. ЧЯДНТ?

 

И последнее: есть ли возможность менять стиль метки кластера?

Пробовал переопределять метод createCluster и вызывать создание экземпляра ymap.Cluster, но класс не определен. Хотя именно он используется для кластера, если верить документации.

21 комментарий

Для кластера:

// массив, описывающий иконки кластера (от маленькой до большой)

var clusterIcons = [{

        href: 'heart.png',

        size: [40, 40],

        // задаем отступ, чтобы метка центрировалась

        offset: [-20, -20]

    }, {

        href: ‘heart.png',

        size: [60, 60], 

        offset: [-30, -30]

     }],

    // задаем массив, указывающий граничные значения размеров кластеров

    // элементов в массиве должно быть на 1 меньше, чем описано меток.

    clusterNumbers = [100],

    clusterer = new ym.Clusterer({

        margin: [20],

        clusterIcons: clusterIcons,

        clusterNumbers: clusterNumbers

    });

clusterer.add(myPlacemarks);

map.geoObjects.add(clusterer);

А как записать условие для формирования 3-х разных иконок кластера?

Например:

1 иконка - если кластер содержит от 1 метки до 20 меток

2 иконка - от 21 метки до 49

3 иконка - от 50

var clusterIcons = [{

        href: 'heart.png',

        size: [40, 40],

        // задаем отступ, чтобы метка центрировалась

        offset: [-20, -20]

    }, {

        href: ‘heart.png',

        size: [60, 60], 

        offset: [-30, -30]

     }, {

     // тут описание третьей картинки

      }],

    clusterNumbers = [20, 50];

o_OИ так просто, спасибо

А как описать вывод иконок для кластера, если условие не количество меток?
Например: Есть две иконки красная и синия. Если кластер содержит метки с красным фоном, то иконка у кластера будет красная и наоборот.
Подскажите. 

как то это не так.
 Вот мой код. У меня два типа меток. Вот и хотелось бы выводить кластер на экран взависимости от того какая это метка User  или Pro. Щас иконки кластера меняются взависимости от числа меток. До 2-ух это одна картинка, после двух это другая картинка.

      geoObjects = [];

      for (var i = 0; i < 500; i++) {

          var coordinates = [

              center[0] + 0.5 * Math.random() * (Math.random() < 0.5 ? -1 : 1),

              center[1] + 0.7 * Math.random() * (Math.random() < 0.5 ? -1 : 1)

          ];

          account = Math.round(Math.random());

          

          if (account == 1 ){

 

            geoObjects[i] = new ymaps.Placemark(coordinates, {            

              content: 'user'

            },{

                iconImageHref: '/images/icon/map/cash-office.png',

                iconImageSize: [53, 49],

                shadow: false,

                balloonLayout: userBalloonLayout,

                balloonShadow: false,

                baloonCloseButton: true

            });

 

          } else {

            

            geoObjects[i] = new ymaps.Placemark(coordinates, {            

              content: 'pro'

            },{

                iconImageHref: '/images/icon/map/cash-office1.png',

                iconImageSize: [53, 49],

                shadow: false,

                balloonLayout: proBalloonLayout,

                balloonShadow: false,

                baloonCloseButton: true

            });     

          }     

      }

      

      var clusterIcons = [{

                href: '/images/icon/map/cluster-icon-user.png',

                size: [36, 48],

                offset: [0, 0]

            },

            {

                href: '/images/icon/map/cluster-icon-pro.png',

                size: [36, 48],

                offset: [0, 0]

            }

        ],      

      clusterNumbers = [2],

      

        clusterer = new ymaps.Clusterer({clusterDisableClickZoom: true,

                                      clusterBalloonLayout: clusterBalloonLayout,

                                      clusterIcons: clusterIcons,

                                      clusterNumbers: clusterNumbers

                                  });

      clusterer.add(geoObjects);

                   

      myMap.geoObjects.add(clusterer);

в кластер не могут попасть метки разных цветов?

Извините, в ходе работы выяснилось что создание кластеров разных цветов не требуется. Извините за беспокойство.)

Макет кнопки закрытия может каидать событие close и тогда все должно работать.

Примерно так
this.events.fire('close');

 

По поводу темплейта балуна примерно так:

 

geoObject1 = new ymaps.Placemark({
            type: "Point",
            coordinates: [0, 55]
        }, {
            name: "Name",
            description: "Description",
            balloonContentFooter: "Footer"
        }, {
            balloonContentLayout: ymaps.templateLayoutFactory.createClass('$[properties.name] $[properties.description]')
            //balloonContentBodyLayout: ymaps.templateLayoutFactory.createClass('$[properties.name] $[properties.description]')
        });

        geoMap.geoObjects.add(geoObject1);

Саш, а можешь написать пример не темлейта, а именно макета,

хотя бы самого простого, например для кнопки закрытия балуна?

того, который передается в опции балуна в ключе "closeButtonLayout",

я просто пробовал его сделать, реализовав интерфейс ILayout, но он ругается

на отсутствие в поле events объекта с методом "setParent", но я не нашел такого  

метода в документации интерфейса IEventManager

Да, есть такой баг в документации. set/getParent забыли описать у менеджера событий.

 

 

geoObject1 = new ymaps.Placemark({
            type: "Point",
            coordinates: [0, 55]
        }, {
            closeButtonUrl: "http://vau.in.ua/i/close_button.gif",
            balloonContentHeader: "Header",
            balloonContentBody: "Body",
            balloonContentFooter: "Footer"
        }, {
            balloonCloseButtonLayout: ymaps.templateLayoutFactory.createClass("", {
                build: function () {
                    this.constructor.superclass.build.call(this);
                    var _this = this;
                    $(this.getParentElement()).click(function (e) {
                        _this._onClick(e);
                    });
                },

                _onClick: function (e) {
                    this.events.fire('close');
                }
            })
        });

 

ух сильно!! спасибо!

Все же templateLayoutFactory это не для слабонервных =),

скажи, а если я не буду им пользоватся,

а буду использовать plain constructor (всмысле просто функцию)

мне придется самому реализовать интерфейс IEventManager в объекте в поле events,

templateLayoutFactory меня от этого освобождает, я правильно понимаю?

Самому реализовывать IEventManager не надо. Есть
http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/event.Manager.xml его надо использовать.

templateLayoutFactory в events его и создает.

 

а в какой момент вызывается build?

что если я хочу при отрытии балуна ходить за его содержимым ajax-ом,

где мне это лучше реализовать?

build вызывается из setParentElement.
его назначение - добавление DOM представления в родитеский элемент.

Если ходить за содержимым ajax'ом, то это лучше делать не из макета.
На мой взгляд, при открытии балуна в макете надо показывать чтото вроде "Загрузка", а когда данные пришли, ты их пишешь в properties, возможно заменяя макет, или не заменяя, если у тебя текущий макет умеет различить по данным, что пора "Закгрузка" сменить на контент.

Даже если задавать темплейт balloonContentLayout, все равно остается стандартный белый бабл (

Я думал вы говорите о содержимом балуна. Если вы хотите заменить весь макет балуна, то нужно задавать свой класс макета в balloonLayout.

Класс задать удалось, но у него почему-то не срабатывает event close.

Если переобпределять лэйаут полностью, то лэйаут кнопки закрытия не используется.

Видимо, надо вешать эвент закрытия на бабл в целом?

Макет балуна должен генерить событие "userclose". Т.к. вы его определяете сами, то вы сами должны решить где у него кнопка закрытия и при клике по этому элементу генерировать "userclose".
Макеты пока задокументированы недостаточно полно, в ближайшее время исправим.