如何在Polymer元素的数组属性上设置观察者?
如何在Polymer元素的数组属性上设置观察者
你的基本思路是对的,使用history.*这种路径观察者确实是Polymer中监听数组变化的正确方式,但有几个细节需要注意,才能确保观察者正常触发:
1. 必须用Polymer的数组操作方法修改数组
Polymer的数组变化检测依赖它包装过的数组方法,如果直接修改数组索引(比如this.history[0] = newItem)或者直接修改数组内部属性,观察者不会触发。你需要用以下方法来操作数组:
push(item1, item2, ...):往数组末尾加元素pop():移除数组最后一个元素splice(index, removeCount, item1, ...):添加/移除指定位置的元素set(index, item):替换数组指定索引的元素unshift(item1, ...):往数组开头加元素shift():移除数组第一个元素
比如在sma-canvas内部修改history时,正确写法是:
// 正确:用Polymer的push方法添加元素 this.push('history', newHistoryItem); // 正确:替换指定索引的元素 this.set('history.0', updatedItem); // 错误:直接修改索引,观察者不会触发 this.history[0] = updatedItem;
2. 完善观察者方法的参数
你的_historyChanged方法可以接收变化对象作为参数,能更精准地知道数组发生了什么变化:
_historyChanged(change) { console.log("History Changed!", change); // change.path: 变化的具体路径,比如"history.0"或"history.splices" // change.value: 变化后的对应值 // change.base: 原数组的引用 this._redrawCanvas(this.$.canvasEl, this.history); }
3. 父元素中修改子元素数组的注意事项
如果在sma-create-studio里操作sma-canvas的history属性:
- 如果是替换整个数组,直接赋值就能触发观察者:
<sma-canvas id="shapesCanvasEdit" history="[[newHistoryArray]]"></sma-canvas>
或者在JS里:
// 用扩展运算符创建新数组,确保引用变化 this.$.shapesCanvasEdit.history = [...newHistoryArray];
- 如果是修改数组内部元素,要调用子元素的数组方法:
// 在父元素中调用子元素的push方法修改数组 this.$.shapesCanvasEdit.push('history', newItem);
完整的正确代码示例
sma-canvas元素代码
class SmaCanvas extends Polymer.Element { static get is() { return 'sma-canvas'; } static get properties() { return { history: { type: Array, value: () => [], // 简化的空数组初始化写法 notify: true } }; } static get observers() { return [ '_historyChanged(history.*)' ]; } _historyChanged(change) { console.log("History Changed!", change); this._redrawCanvas(this.$.canvasEl, this.history); } // 示例:内部添加历史项的方法 addHistoryItem(item) { this.push('history', item); } } customElements.define(SmaCanvas.is, SmaCanvas);
sma-create-studio元素代码
<dom-module id="sma-create-studio"> <template> <sma-canvas id="shapesCanvasEdit" history="{{studioHistory}}"></sma-canvas> <button on-click="_addHistory">添加历史记录</button> </template> <script> class SmaCreateStudio extends Polymer.Element { static get is() { return 'sma-create-studio'; } static get properties() { return { studioHistory: { type: Array, value: () => [], notify: true } }; } _addHistory() { // 方式1:通过双向绑定修改数组(会自动触发子元素的观察者) this.push('studioHistory', {timestamp: Date.now()}); // 方式2:直接调用子元素的方法修改数组 // this.$.shapesCanvasEdit.addHistoryItem({timestamp: Date.now()}); } } customElements.define(SmaCreateStudio.is, SmaCreateStudio); </script> </dom-module>
总结一下,核心就是:用Polymer提供的数组操作方法修改数组,确保变化能被框架检测到,观察者就能正常触发啦!
内容的提问来源于stack exchange,提问作者Shahid Nauman
相关产品推荐
相关产品推荐

