在Polymer元素之间传递数组和/或对象数据

eri*_*per 6 javascript json google-maps google-maps-api-3 polymer

我正在设置一个名为"locator-map"的自定义谷歌地图聚合物元素,它使用polymer-jsonp从谷歌电子表格中获取数据,获取响应,然后将其发送到自定义的"google-map"元素以绘制地图上的标记.我似乎无法弄清楚如何将从polymer-jsonp元素返回的数据实际注入到我的google-map元素中,以便它可以使用它来构建标记.

这是我的数据来源:https: //spreadsheets.google.com/feeds/list/0Ao_YrKZEsc4AdGppeG1zaGotRDd0LUdIYk9tdW9VZnc/od6/public/values?alt=json-in-script

我按照这里的指示进行了初步设置:http: //www.html5rocks.com/en/tutorials/webcomponents/yeoman/

我的locator-map元素的代码:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/polymer-jsonp/polymer-jsonp.html">
<link rel="import" href="google-map.html">

<polymer-element name="locator-map" attributes="">
  <template>
      <style>
          /* styles for the custom element itself - lowest specificity */
          :host { display: block; }
          google-map {
              display:block;
              height:600px;
          }
      </style>

      <!-- Load Data with JSONP Endpoint (in this case Google Spreadsheets)
          Format: https://spreadsheets.google.com/feeds/list/0AhcraNy3sgspdDhuQ2pvN21JVW9NeVA0M1h4eGo3RGc/od6/public/values?alt=json-in-script&callback=
          Source: https://docs.google.com/spreadsheet/ccc?key=0AqZBbhllhMtHdFhFYnRlZk1zMzVZZU5WRnpLbzFYVFE&usp=sharing
      -->
      <polymer-jsonp auto url="https://spreadsheets.google.com/feeds/list/0Ao_YrKZEsc4AdGppeG1zaGotRDd0LUdIYk9tdW9VZnc/od6/public/values?alt=json-in-script&callback=" response="{{locations}}"></polymer-jsonp>

      <ul>
          <template repeat="{{location in locations.feed.entry}}">
              <li>Name: {{location.gsx$name.$t}}
                <ul><li>Lat: {{location.gsx$lat.$t}}</li><li>Long: {{location.gsx$lng.$t}}</li></ul>
              </li>
          </template>
      </ul>

      <!-- Load the Google Map -->
      <google-map map="{{map}}" latitude="45.526158" longitude="-122.679394" zoom="14" markers="{{locations}}"></google-map>

  </template>
  <script>
    Polymer('locator-map', {
      // element is fully prepared
      ready: function(){
      },
      // instance of the element is created
      created: function() { },
      // instance was inserted into the document
      enteredView: function() { },
      // instance was removed from the document
      leftView: function() { },
      // attribute added, removed or updated
      attributeChanged: function(attrName, oldVal, newVal) { }
    });
  </script>
</polymer-element>
Run Code Online (Sandbox Code Playgroud)

我的google-map元素的代码:

<link rel="import" href="../bower_components/polymer/polymer.html">

<polymer-element name="google-map" attributes="latitude longitude zoom showCenterMarker map markers">
    <template>
        <style>
            :host {
                position: relative;
            }

            #map {
                position: absolute;
                top: 0;
                right: 0;
                bottom: 0;
                left: 0;
            }
        </style>

        <div id="map"></div>
    </template>
    <script>
        (function() {
            var CALLBACK_NAME = 'polymer_google_map_callback';
            var MAP_URL = 'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&sensor=false&callback=' + CALLBACK_NAME;
            var pendingCallbacks = [];
            var loading;

            function loadMapApi(callback) {
                if (window.google && window.google.maps) {
                    callback();
                    return;
                }
                if (!loading) {
                    loading = true;
                    window[CALLBACK_NAME] = mapApiLoaded.bind(this);
                    var s = document.createElement('script');
                    s.src = MAP_URL;
                    document.head.appendChild(s);
                }
                pendingCallbacks.push(callback);
            }

            function mapApiLoaded() {
                delete window[CALLBACK_NAME];
                pendingCallbacks.forEach(function(callback) {
                    callback();
                });
            }

            Polymer('google-map', {
                latitude: '37.77493',
                longitude: '-122.41942',
                zoom: 10,
                showCenterMarker: false,
                observe: {
                    latitude: 'updateCenter',
                    longitude: 'updateCenter'
                },
                ready: function() {
                    loadMapApi(this.mapReady.bind(this));
                },
                created: function() {
                },
                enteredView: function() {
                    this.resize();
                },
                mapReady: function() {

                    // Create the Map
                    this.map = new google.maps.Map(this.$.map, {
                        zoom: this.zoom,
                        center: new google.maps.LatLng(this.latitude, this.longitude)
                    });

                    // Show Center Marker
                    this.showCenterMarkerChanged();

                    // Add Markers (if any supplied)
                    this.addMarkers();

                    // Fire the Map Ready Event
                    this.fire('google-map-ready');
                },
                resize: function() {
                    if (this.map) {
                        google.maps.event.trigger(this.map, 'resize');
                        this.updateCenter();
                    }
                },
                updateCenter: function() {
                    if (!this.map) {
                        return;
                    }
                    this.map.setCenter(
                            new google.maps.LatLng(this.latitude, this.longitude));
                    this.showCenterMarkerChanged();
                },
                zoomChanged: function() {
                    if (this.map) {
                        this.map.setZoom(Number(this.zoom));
                    }
                },
                showCenterMarkerChanged: function() {
                    if (!this.map) {
                        return;
                    }
                    if (!this.centerMarker && this.showCenterMarker) {
                        this.centerMarker = new google.maps.Marker({
                            map: this.map
                        });
                    }
                    if (this.centerMarker) {
                        this.centerMarker.setPosition(this.map.getCenter());
                        this.centerMarker.setMap(this.showCenterMarker ? this.map : null);
                    }
                },

                /*
                 * Add Markers
                 * Adds markers to the map.  Expects an array of objects specifying the location information via name, lat and lng properties.
                 *
                 * @author erikharper
                 */
                addMarkers: function()
                {
                    console.log("Markers: ");
                    console.log(this.markers);

                    // Get the Map instance
                    var map = this.map;

                    if(this.markers.isArray())
                    {
                        // Create each Marker on the Map
                        this.markers.forEach(function(marker){

                            // Create a LatLng object
                            var markerLatLng = new google.maps.LatLng(marker.lat, marker.lng);

                            // Create the Marker object and add it to the map via the map property
                            new google.maps.Marker({
                                map: map,
                                position: markerLatLng,
                                title: marker.name
                            });
                        });
                    }

                }

            });
        })();
    </script>
</polymer-element>
Run Code Online (Sandbox Code Playgroud)

在我的控制台上,我得到一个"this.markers为null".我究竟做错了什么?

ebi*_*del 10

你有markers="{{locations}}",这是polymer-jsonp组件的纯JSON响应.我必须先转换数据并解析lat/lng:

var markers = [];
markers.push({
  lat: parseFloat(entry.gsx$lat.$t),
  lng: parseFloat(entry.gsx$lng.$t),
  name: entry.gsx$name.$t
});
this.markers = markers;
Run Code Online (Sandbox Code Playgroud)

我接近的方法是重用现有的Polymer google-map元素:http://jsbin.com/wowuledo/6/edit

重要的一点是,当this.markers数组发生变化时,markersChanged会被调用,然后调用你的addMarkers(我修改过):

  markersChanged: function() {
    this.addMarkers();
  },
  addMarkers: function() {
    this.markers.forEach(function(marker) {
      var marker = new google.maps.Marker({
        map: this.map,
        position:  new google.maps.LatLng(marker.lat, marker.lng),
        title: marker.name
      });
    }.bind(this));
  }
Run Code Online (Sandbox Code Playgroud)

如果必须创建一个额外的元素来添加自己的属性/方法,为什么不继承google-maps

<polymer-element name="google-map-with-markers" extends="google-map" attributes="markers">
Run Code Online (Sandbox Code Playgroud)

这样,您可以获得所有功能google-maps,但可以数据绑定到已markers发布的属性:

<google-map-with-markers latitude="45.526158" longitude="-122.679394" zoom="14" markers="{{markers}}"></google-map-with-markers>
Run Code Online (Sandbox Code Playgroud)

试试:http://jsbin.com/renuyifu/1/edit