[英]Polymer 1.x: Databinding Arrays
我想将此元素中的selected
属性数据绑定到DOM(在<div>[[selected]]</div>
)。
选择一个州(例如“德克萨斯州”)后,我希望该州的名称出现在“科罗拉多州,南达科他州”预选州旁边的左上方(在<div>[[selected]]</div>
标签)。 但是,事实并非如此。
这里发生了什么? 如何成功将DOM绑定到selected
属性? 并让DOM自动随着选中和取消选中的每个新状态进行更新。
跟着这些步骤:
<div>[[selected]]</div>
selected
阵列中。 这个SO答案解释了为什么Polymer对象不能直接观察到变异数组 。
@ScottMiles写道:...您正在做Polymer无法看到的工作(即数组操作),然后要求
set
找出发生了什么。 但是,当您调用this.set('selected', selected);
,Polymer看到selected
的标识没有改变(也就是说,它与以前的Array对象相同),并且只是停止处理。
因此,我尝试通过在原始数组上使用.slice()
方法创建一个新数组来解决此问题,如下所示。
// Sort new 'selected' array _selectedChanged: function(selectedInfo) { var selected = this.selected.slice(); selected.sort(); //this.set('selected', selected); // Uncommenting this line crashes call stack },
这似乎解决了可观察性问题,但产生了副作用,并使调用堆栈崩溃。
<!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="google-chart/google-chart.html" rel="import"> </head> <body> <dom-module id="x-element"> <template> <style> google-chart { width: 100%; } </style> <br><br><br><br> <button on-tap="_show">Show Values</button> <button on-tap="clearAll">Clear All</button> <button on-tap="selectAll">Select All</button> <div>[[selected]]</div> <google-chart id="geochart" type="geo" options="[[options]]" data="[[data]]" on-google-chart-select="_onGoogleChartSelect"> </google-chart> </template> <script> (function() { // google-chart monkey patch var gcp = Object.getPrototypeOf(document.createElement('google-chart')); gcp.drawChart = function() { if (this._canDraw) { if (!this.options) { this.options = {}; } if (!this._chartObject) { var chartClass = this._chartTypes[this.type]; if (chartClass) { this._chartObject = new chartClass(this.$.chartdiv); google.visualization.events.addOneTimeListener(this._chartObject, 'ready', function() { this.fire('google-chart-render'); }.bind(this)); google.visualization.events.addListener(this._chartObject, 'select', function() { this.selection = this._chartObject.getSelection(); this.fire('google-chart-select', { selection: this.selection }); }.bind(this)); if (this._chartObject.setSelection){ this._chartObject.setSelection(this.selection); } } } if (this._chartObject) { this._chartObject.draw(this._dataTable, this.options); } else { this.$.chartdiv.innerHTML = 'Undefined chart type'; } } }; Polymer({ is: 'x-element', /** / * Fired when user selects chart item. * * @event us-map-select * @param {object} detail Alpabetized array of selected state names. /**/ properties: { items: { type: Array, value: function() { return [ 'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming', ].sort(); }, }, color: { type: String, value: 'blue', }, options: { type: Object, computed: '_computeOptions(color)', }, selected: { type: Array, value: function() { return []; } }, data: { type: Array, computed: '_computeData(items, selected.length)' }, }, observers: [ '_selectedChanged(selected.length)', ], _computeOptions: function() { return { region: 'US', displayMode: 'regions', resolution: 'provinces', legend: 'none', defaultColor: 'white', colorAxis: { colors: ['#E0E0E0', this.color], minValue: 0, maxValue: 1, } } }, // On select event, compute 'selected' _onGoogleChartSelect: function(e) { var string = e.path[0].textContent.split('Select')[0].trim(), // eg 'Ohio' selected = this.selected, // Array of selected items index = selected.indexOf(string); // If 'string' is not in 'selected' array, add it; else delete it if (index === -1) { this.push('selected', string); } else { this.splice('selected', index, 1); } }, // Sort new 'selected' array _selectedChanged: function(selectedInfo) { var selected = this.selected.slice(); selected.sort(); //this.set('selected', selected); // Uncommenting this line crashes call stack }, // After 'items' populates or 'selected' changes, compute 'data' _computeData: function(items, selectedInfo) { var data = [], selected = this.selected, i = items.length; while (i--) { data.unshift([items[i], selected.indexOf(items[i]) > -1 ? 1 : 0]); } data.unshift(['State', 'Select']); return data; }, clearAll: function() { this.set('selected', []); }, selectAll: function() { this.set('selected', this.items); }, _show: function() { //console.log('items', this.items); console.log('selected', this.selected); //console.log('data', this.data); }, }); })(); </script> </dom-module> <x-element color="red" selected='["Colorado", "South Dakota"]'></x-element> </body> </html>
如果要绑定数组,则必须使用dom-repeat。
<template is="dom-repeat" items="[[selected]]">[[item]] </template>
dom-repeat
的格式不支持正确使用逗号分隔符。 所以我改用了一个计算属性字符串。
<div>[[selectedString]]</div> ... selectedString: { type: String, computed: '_computeSelectedString(selected.length)', }, ... _computeSelectedString: function(selectedInfo) { return this.selected.sort().join(', '); },
数据绑定数组可能很棘手。
http://jsbin.com/xonanucela/edit?html,控制台,输出 <!doctype html> <head> <meta charset="utf-8"> <base href="https://polygit.org/components/"> <script src="webcomponentsjs/webcomponents-lite.min.js"></script> <link href="paper-button/paper-button.html" rel="import"> </head> <body> <x-element></x-element> <dom-module id="x-element"> <template> <br><br> <paper-button on-tap="_addNew">Click To Add</paper-button> <p> <strong>Items</strong>: <template is="dom-repeat" items="{{items}}"> <span>[[item]] </span> </template> </p> </template> <script> Polymer({ is: 'x-element', properties: { items: { type: Array, value: function() { return ['foo']; } } }, _addNew: function() { var a = this.items; // Clones array a.push('bar'); // Updates "value" console.log('a', a); this.set('items', a.slice()); // Updates "identity" console.log('items', this.items); }, }); </script> </dom-module> </body>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.