[英]Strange behavior in Polymer data-binding to an attribute
使用Polymer 1.0,我試圖綁定到自定義元素的屬性,並僅顯示它。
自定義元素實際上是<iron-input>
列表,具有添加和刪除按鈕。 我想將該列表中的任何更改反映給主持人。 它還具有minItemSize
屬性,這意味着它至少具有這么多的元素。 因此,我向觀察者添加了一個檢查,並添加了其他元素,以防它低於此數字。
但是,當我綁定到保存列表的屬性時,事情就變得不同步了,我可以從ui中刪除所有輸入。
我有兩個<dyn-inputlist>
元素。 在其中一個中,我不綁定到data
屬性,在另一個中,我綁定。
第一個行為符合預期:單擊按鈕時添加和刪除。
另一個不起作用,因為您可以刪除所有輸入框。 即使數據本身已更新並充滿了其他項目,但由於某些原因,UI仍未反映出這一點。 (檢查元素的data屬性確實表明它具有正確的項目數)
我還希望,如果我在兩個dyn-inputlist
元素上都設置了data={{myData}}
,它們總是顯示相同的內容。 但是,在每個組件上隨機按下添加/刪除按鈕會使它們不同步。
我想念什么嗎? 提前致謝。
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="components/dyn-inputlist.html"/>
</head>
<body>
<template is="dom-bind">
<dyn-inputlist min-item-size="4"></dyn-inputlist>
<div>{{mydata}}</div>
<dyn-inputlist min-item-size="4" data="{{mydata}}"></dyn-inputlist>
</template>
</body>
</html>
dyn-inputlist.html
:
<link rel="import" href="../../polymer/polymer.html">
<link rel="import" href="../../iron-input/iron-input.html">
<dom-module id="dyn-inputlist">
<template>
<button on-click="removeItem">x</button>
<button on-click="addItem">+</button>
<template is="dom-repeat" items="{{data}}">
<div>
<span>{{index}}</span>
<input is="iron-input" bind-value="{{item.content}}">
</div>
</template>
</template>
<script>
Polymer({
is: 'dyn-inputlist',
properties: {
minItemSize: {
type: Number,
notify: true,
value: 1
},
data: {
type: Array,
reflectToAttribute: true,
notify: true,
value: function () {
return []
}
}
},
observers: ['_dataChanged(data.*)'],
addItem: function (e) {
this.unshift('data', {content: ""});
this.reflectPropertyToAttribute('data')
},
removeItem: function (e) {
this.shift('data');
this.reflectPropertyToAttribute('data')
},
_dataChanged: function (e) {
if (this.data != null) {
while (this.data.length < this.minItemSize) {
this.push('data', {content: ""})
}
} else {
this.data = [{content: ""}];
}
this.reflectPropertyToAttribute('data');
}
});
</script>
</dom-module>
編輯:這是實時代碼: http : //jsbin.com/poquke/1/edit?html,輸出
我已經對您的代碼進行了一些嘗試,我注意到如果將代碼包裝在異步函數中的已更改處理程序中,它將可以正常工作。 這解決了您描述的兩個問題。
_dataChanged: function (e) {
this.async(function(){
if (this.data != null) {
while (this.data.length < this.minItemSize) {
this.push('data', {content: ""})
}
} else {
this.data = [{content: ""}];
}
});
}
對於這種行為,我沒有一個完美的解釋。 我認為這與Polymer處理變化觀察的方式有關。 每次您在更改后的處理程序中推送到數據數組時,實際上這都會更改數據,從而應再次觸發該處理程序。
如果您簡化,則不需要異步。
這是簡化的代碼,當您推入最小值時,它消除了對_dataChanged的重復調用,並允許Polymer的內置事件系統負責更新和通知其他元素。 函數:_createNewItem()用於創建對象。 這簡化了處理項目對象創建的位置。
http://jsbin.com/vemita/6/edit?html,output
鏈接和URL參考已從上面問題中的示例代碼更改為與Polyserve一起使用的聚合物元素和演示頁面標准一致。
我已經對您的原始代碼發表了評論,說明了每行應該或不應該出現的原因。 這包括更改_dataChanged的原因
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.