Why would an element be limited to only one instance in Polymer 1.x? -
i created custom element called <us-map-select>
, want use twice in app. so:
<us-map-select></us-map-select> <us-map-select></us-map-select>
when use once (as follows), works.
<us-map-select></us-map-select>
but when use twice (as follows), app breaks , see blank page.
<us-map-select></us-map-select> <us-map-select></us-map-select>
i think might have of following lines in code might conflicting when multiple instances in play. potentially problematic lines follows...
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> ... google.charts.setonloadcallback(this._drawregionsmap.bind(this));
the full code can seen in jsbin (and below):
question
http://jsbin.com/gihezatigo/1/edit?html,console,outputcan tell me might causing second simultaneous instance of element "break" app?
<!doctype html> <head> <meta charset="utf-8"> <base href="https://polygit.org/components/"> <script src="webcomponentsjs/webcomponents-lite.min.js"></script> <link href="polymer/polymer.html" rel="import"> <link href="iron-selector/iron-selector.html" rel="import"> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="https://www.google.com/jsapi"></script> </head> <body> <dom-module id="x-element"> <template> <style> #geochart { width: 100%; max-height: 500px; } </style> <button on-tap="_show">show</button> <button on-tap="clearall">clear all</button> <button on-tap="selectall">select all</button> <div id="geochart"></div> <div hidden id="selectmirror"> <iron-selector id="selector" activate-event="" selected-values="{{selectedstates}}" multi attr-for-selected="name"> <template is="dom-repeat" items="[[items]]"> <span name="[[item.0]]"></span> </template> </iron-selector> </div> </template> <script> (function(){ polymer({ is: 'x-element', properties: { items: { type: array, notify: true, value: function() { return [['state', 'select'], ['alabama', 0], ['alaska', 0], ['arkansas', 0], ['arizona', 0], ['california', 0], ['colorado', 0], ['connecticut', 0], ['delaware', 0], ['florida', 0], ['georgia', 0], ['hawaii', 0], ['iowa', 0], ['idaho', 0], ['illinois', 0], ['indiana', 0], ['kansas', 0], ['kentucky', 0], ['louisiana', 0], ['massachusetts', 0], ['maryland', 0], ['maine', 0], ['michigan', 0], ['minnesota', 0], ['missouri', 0], ['mississippi', 0], ['montana', 0], ['north carolina', 0], ['north dakota', 0], ['nebraska', 0], ['new hampshire', 0], ['new jersey', 0], ['new mexico', 0], ['nevada', 0], ['new york', 0], ['ohio', 0], ['oklahoma', 0], ['oregon', 0], ['pennsylvania', 0], ['rhode island', 0], ['south carolina', 0], ['south dakota', 0], ['tennessee', 0], ['texas', 0], ['utah', 0], ['virginia', 0], ['vermont', 0], ['washington', 0], ['wisconsin', 0], ['west virginia', 0], ['wyoming', 0]]; } }, options: { type: object, notify: true, value: { region: 'us', displaymode: 'regions', resolution: 'provinces', legend: 'none', } }, chart: { type: object, notify: true, //computed: '_computechart()', }, selectedstates: { type: array, notify: true, reflecttoattribute: true, value: function () { return []; } }, }, observers: [ '_selectedchanged(selectedstates.*)' ], _selectedchanged: function () { this.items.foreach(function (stateitem, index) { if (!index) return; this.set('items.' + index + '.1', 0); }.bind(this)); this.selectedstates.foreach(function (selectedstate) { var index = null; this.items.some(function (state, stateindex) { if (state[0] === selectedstate) { index = stateindex; return true; } return false; }); this.set('items.' + index + '.1', 1); }.bind(this)); this.selectedstates.sort(); if (google.visualization && this._rendermap) { this._drawregionsmap(); } else { this._rendermap = true; } }, _computechart: function() { var out = new google.visualization.geochart(this.$.geochart); google.visualization.events.addlistener(out, 'select', this._selecthandler.bind(this)); return out; }, data() { return google.visualization.arraytodatatable(this.items); }, ready: function(){ google.charts.load('current', { 'packages': ['geochart'] }); google.charts.setonloadcallback(this._drawregionsmap.bind(this)); }, clearall: function() { this.set('selectedstates', []); }, selectall: function() { var ar = [], = this.items, = a.length; while(i---1){ ar.push(a[i][0]); } ar.sort(); this.set('selectedstates', ar); }, _drawregionsmap: function() { this.set('chart', this._computechart()); this.chart.draw(this.data, this.options); }, _selecthandler: function() { var selecteditem = this.chart.getselection(); var row = selecteditem[0].row; var value = this.data.getvalue(row, 0); this._rendermap = false; this.$.selector.select(value); }, _show: function() { //console.log(this.items); //console.log(this.data); //console.log(this.chart); console.log(this.selectedstates); }, }); })(); </script> </dom-module> <x-element selected-states='["ohio"]'></x-element> </body>
you not allowed call google.charts.load
more once. crude solution create closure-variable flag synchronize loading state of charts api.
so, @ top have closure:
(function(){ var chartstatus = '';
then add _syncchartapi method take care of managing state.
ready: function(){ this._syncchartapi(); }, _syncchartapi: function() { switch (chartstatus) { case '': chartstatus = 'loading' google.charts.load('current', { 'packages': ['geochart'] }); case 'loading': google.charts.setonloadcallback(function() { chartstatus = 'loaded'; this._drawregionsmap(); }.bind(this)); break; case 'loaded': this._drawregionsmap(); break; } },
http://jsbin.com/pibepis/7/edit?html,output
i provide above educational value. :)
as @tjwato says, should official google-chart implementation has more sophisticated synchronization.
Comments
Post a Comment