Привязка массива объектов к шаблону, содержащему элементы google-map-marker

У меня есть это <dom-module> со свойством locations типа Array, которое время от времени обновляется извне:

<dom-module id="my-map">
    <template>
        <google-map api-key="MY_API_KEY" id="map" libraries="visualization,geometry,drawing">
            <template is="dom-repeat" items="{{locations}}" as="user">
                <template is="dom-repeat" items="{{user.trace}}">
                    <google-map-marker latitude="{{item.latitude}}" longitude="{{item.longitude}}">
                    </google-map-marker>
                </template>
            </template>
        </google-map>
    </template>
</dom-module>
<script>
Polymer({
    is : 'my-map',
    properties : {
        locations : {
            type : Array,
            value : [],
            observer : '_locationsChanged'
        }
    },
    ready : function(){
        var self = this;
        this.map = this.querySelector('google-map');
        this.map.addEventListener('google-map-ready',function(){
            // some styling happening here.
        });
    },
    _locationsChanged : function(newLocations, oldLocations){
        // this fires correctly! ...
    }
});
</script>

В другом модуле я отправляю запрос AJAX для получения данных, которые будут отображаться в виде маркеров на карте. Как только запрос завершается, я обновляю свойство location, и обратный вызов _locationsChanged срабатывает отлично.

Данные в этом случае выглядят примерно так:

[  
    {  
      "_id":"someID1",
      "trace":[  
        {  
          "latitude":55.629215086862,
          "longitude":10.640099246067,
        }
      ]
    },
    {  
      "_id":"someID2",
      "trace":[  
        {  
          "latitude":50.14743798944287,
          "longitude":18.52913082363756,
        }
      ]
    }
]

Происходит что-то странное.

Всякий раз, когда местоположения являются пустым массивом, newLocations без проблем привязываются к элементу <template dom-repeat="{{locations}}">. Однако, если на карте уже была отмечена пара маркеров, старые <google-map-marker> объекты остались, новые просто добавлены. Поэтому, если я сделаю это в консоли разработчика document.querySelectorAll('google-map-marker') после обновления до locations, я увижу как newLocations , так и oldLocations.

Чтобы проверить правильность работы привязки данных вне элемента <google-map>, я добавил аналогичный шаблон. Здесь все работает идеально, как и ожидалось:

<template is="dom-repeat" items="{{locations}}" as="user">
    <ul>
        <li>
            <span>{{user._id}}</span>
            <ul>
                <template is="dom-repeat" items="{{user.trace}}" as="trace">
                    <li><span>Lat:</span><span>{{trace.latitude}}</span></li>
                </template>
            </ul>
        </li>
    </ul>
</template>

Вот что пока не помогло:

  • Вызов clear() для объекта GoogleMap.
  • создание второго свойства, привязанного к шаблону dom-repeat, но с доступом к вот так:
    this.splice('_locations',0,this._locations.length);
    newLocations.forEach(function(location){
        self.push('_locations',location);
    });
  • с помощью односторонней привязки данных.
  • вручную удаляя узлы DOM через googleMap.removeChild(marker) и добавляя их. Хорошо, в какой-то степени это действительно сработало, но разве весь смысл привязки данных не в том, что вам не нужно этого делать?

Итак, подведем итог: <template is="dom-repeat"> внутри карты Google не получает корректных уведомлений об изменениях в свойстве locations. Может ли кто-нибудь сказать мне, что я делаю неправильно или не работает привязка данных внутри элемента <google-map>? Я путаю вещи с теневым/теневым DOM? Я неправильно использую dom-repeat? Я сойду с ума? Я буду признателен за любой намек на решение. Спасибо!


person LeBird    schedule 02.06.2015    source источник
comment
Вы также можете назначить наблюдателя в dom-repeat. Прочтите документацию: polymer-project.org /1.0/docs/devguide/   -  person Kay_N    schedule 04.06.2015


Ответы (1)


Я не уверен, имеет ли это значение для вашей конкретной проблемы, но значения по умолчанию для массивов и объектов должны быть указаны в этом format (см. атрибут value):

 properties : {
        locations : {
            type : Array,
            value : function() { return [];},
            observer : '_locationsChanged'
        }
    },

Я также думаю, что вы должны вызывать clear() для элемента google-map, потому что функция _updateMarkers() не делает этого за вас (см. здесь)

person Ümit    schedule 04.06.2015