我创建了一个名为<us-map-select>
的自定义元素,并希望在我的应用中使用它两次。像这样:
<us-map-select></us-map-select>
<us-map-select></us-map-select>
当我使用它一次(如下)时,它可以工作。
<us-map-select></us-map-select>
但是当我使用它两次(如下所示)时,应用程序会断开,我会看到一个空白页面。
<us-map-select></us-map-select>
<us-map-select></us-map-select>
我认为这可能与我的代码中的以下某些行有关,这些行在多个实例正在运行时可能会发生冲突。可能存在问题的行如下......
<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 be seen in this jsBin(及以下):
http://jsbin.com/gihezatigo/1/edit?html,console,output任何人都可以告诉我可能导致我的元素的第二个同步实例导致&#34; break&#34;我的应用程序?
<!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;
},
get 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 = [],
a = this.items,
i = 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>
答案 0 :(得分:3)
您不得多次拨打google.charts.load
。一个粗略的解决方案是创建一个闭包变量作为标志来同步图表api的加载状态。
所以,在你已经有一个闭包的顶部:
(function(){
var chartStatus = '';
然后添加_syncChartApi方法来处理状态。
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
我提供以上内容主要是为了教育价值。 :)
正如@Tjwato所说,您应该查看官方google-chart实施,因为它具有更复杂的同步。
答案 1 :(得分:1)
据我所知,Google图表API不希望同时运行两个自身实例。 Similar Problem
我建议调查google-chart元素。从我所知道的,它可以做你想要的一切。希望这会有所帮助。