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

can tell me might causing second simultaneous instance of element "break" app?

http://jsbin.com/gihezatigo/1/edit?html,console,output
<!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

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

dataset - MPAndroidchart returning no chart Data available -

java - No use of nillable="0" in SOAP Webservice -