Клуб API Карт

Почему setContent срабатывает дважды?

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

Исходник: http://ymaps.narod2.ru/examples/markersimplelayout.html

Код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Примеры. Почему setContent срабатывает дважды?</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <script src="http://api-maps.yandex.ru/1.1/index.xml?key=apiKey" type="text/javascript"></script>
    <script type="text/javascript">
        // Создание обработчика для события window.onLoad
        YMaps.jQuery(function () {
 
            // Создание экземпляра карты и его привязка к созданному контейнеру
            var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]) ;
 
            // Установка для карты ее центра и масштаба
            map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10) ;
 
            // Создание метки
            placemark = new YMaps.Placemark(map.getCenter(), {style: {
                iconStyle : {
                    template : new YMaps.LayoutTemplate(PlacemarkLayout)
                }
            }}) ;
 
            // Добавление нужной информации
            placemark.setIconContent('метка 1') ;
 
            // Добавление новой метки на карту
            map.addOverlay(placemark) ;
 
            // Добавление нужной информации
            placemark.setIconContent('метка 2') ;
 
            // Макет для метки
            function PlacemarkLayout () {
                var element = YMaps.jQuery('<div class="MyPlacemark"/>') ;
 
                this.onAddToParent = function (parent) {
                    element.appendTo(parent) ;
                }
 
                this.onRemoveFromParent = function () {
                    element.remove() ;
                }
 
                this.update = function () {
                    console.log('update') ;
                }
 
                this.setContent = function (content) {
                    console.log('setContent:', content._text) ;
                }
            }
        }) ;
    </script>
</head>
<body>
    <div id="YMapsID" style="height: 500px;"></div>
</body>
</html>

 

На выходе:
setContent: метка 1
setContent: метка 2
setContent: метка 2
update

 

И как получить доступ к содержимому, устанавливаемому методом setContent(), не обращаясь к _text?

4 комментария

Срабатывает судя по всему случайно.

Вы на самом деле нашли даже две ошибки - так как к _text доступа быть не должно(все переменные _XXX - "устрашняются" на этапе сборки скрипта уже как несколько лет)

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

Требуется передать в setIconContent либо ноду, либо некий обьект с любыми полями.

В данном случае в своей функции вы получите именно то что хотели без каких либо изменений.

Спасибо за ответ!

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

У интерфейса IContentableLayout нет методов для доступа к контенту, во всех примерах предлагается воспользоваться content.onAddToParent(). Если это единственный путь, для чего тогда предназначен setContent()?

Если в параметре setIconContent() я передаю строку или объект, в какой момент они начинают реализовывать IContentableLayout? Как с ними работать?

скажем просто - если в setContent вы передаете текст - он оборачивается в шаблон и передается в вашу функцию для того чтобы вы его вставили.

Это именно то что вы видите сейчас.

Если передадите туда дом-ноду или обьект - в вашу функцию прийдут именно эти данные(без каких либо изменений), и что с ними делать - ваши проблеммы :)

например

placemark.setIconContent({html:'blabla'});

....

setContent = function (content) { element.html(content.html);}

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

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