[英]Polymer 3: How to implement two way data binding for radio input
我正在嘗試理解/實現Polymer 3 Web組件中的雙向屬性綁定。 我有以下代碼:
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
class CustomInputComponent extends PolymerElement {
static get template() {
return html`
<div>
<template is="dom-repeat" items="{{ratings}}">
<input type="radio"
name="group"
id="item_{{item.id}}"
value="{{item.checked}}"
checked$="{{item.checked}}">
</template>
</div>`;
}
static get properties() {
return {
ratings: {
type: Array,
value: [
{ id: 1, checked: true },
{ id: 2, checked: false }
]
}
};
}
}
window.customElements.define('custom-input-component', CustomInputComponent);
如您所見,我已經定義了一個包含默認值列表的Array屬性。 此屬性是我想要渲染無線電組的模型。 初始狀態看起來不錯。 但是,當我單擊未選中的輸入時,DOM元素無法正確更新。
我敢打賭,我錯過了一些非常簡單的事情......
主要的是:
您綁定到checked
屬性( $=
),但我不認為無線電輸入會動態更新其已checked
屬性。 AFAICT, checked
屬性是選擇輸入時的更改。
此外,原生<input type="radio">
輸入只會在選擇它們時觸發它們的change
和input
事件,而不是在取消選擇它們時。 Polymer依賴於事件來觸發數據綁定等屬性效果; 這意味着只有當輸入上的checked
屬性從false
變為true
時,才會處理向上數據綁定(從輸入到自定義元素)。 實際上,一旦ratings[n].checked
變為true,它將永遠不會被偽造,因為Polymer無法知道這已經發生了。
順便提一下,要對本機HTML元素執行雙向綁定, 您還需要為選中時無線電輸入觸發的事件添加注釋 。 因此,如果您確實想要捕獲選擇上的更改,那就像checked="{{item.checked::change}}"
。
有兩種選擇:
在paper-radio-group
使用paper-radio-button
而不是本機<input>
。 這些元素對於雙向數據綁定表現良好。
在檢查新項目時監聽更改,並手動將先前所選項目的ratings[n].checked
更新為false
。
關於代碼的更多內容
(我不認為這與你當前的問題有什么關系,但它有助於避免將來的問題)在Polymer元素中初始化對象或數組屬性的默認值時, 記得使用一個函數使每個元素實例獲得自己獨特的數組或對象。 例如:
ratings: { type: Array, value: function(){ return [ { id: 1, checked: true }, { id: 2, checked: false } ]; } }
通常我認為,您不希望更改無線電輸入的值 。 傳統上,當提交包含無線電輸入組的<form>
時,當前checked
的無線電輸入上的value
被包括在表格數據中,並且忽略其他無線電輸入值。 這是W3Schools的一個例子 。 因此,而不是value="{{item.checked}}"
,類似於value="[[item.data]]"
。
所以整個事情可能就像
class CustomInputComponent extends PolymerElement {
static get properties () {
return {
ratings: {
type: Array,
value: function(){
return [
{ id: 1, checked: true, value: 'pie' },
{ id: 2, checked: false, value: 'fries' },
{ id: 3, checked: false, value: 'los dos' }
];
}
},
selected: {
// type: Number or Object, idk
// Keep track of the selected <input>
}
};
}
static get template() {
return html`
<p>do you want pie or fries?</p>
<div id="mydiv">
<template is="dom-repeat" items="{{ratings}}">
<input
type="radio"
name="testgroup"
id="[[item.id]]"
value="[[item.value]]"
checked="{{item.checked::input}}"
on-change="radioChanged"
>[[item.value]]
</input>
</template>
</div>
`;
}
radioChanged(event){
// update ratings[n].checked for selected input
// set selected input to currently selected input
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.