簡體   English   中英

聚合物3:如何實現無線電輸入的雙向數據綁定

[英]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">輸入只會在選擇它們時觸發它們的changeinput事件,而不是在取消選擇它們時。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM