【问题标题】:Polymer 3: How to implement two way data binding for radio inputPolymer 3:如何实现无线电输入的两种方式数据绑定
【发布时间】:2018-06-15 16:13:19
【问题描述】:

我正在尝试在 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 元素不会正确更新。

我敢打赌我错过了一些非常简单的东西......

【问题讨论】:

    标签: javascript polymer web-component polymer-3.x


    【解决方案1】:

    主要是:

    • 您正在绑定到 checked 属性 ($=),但是我认为无线电输入不会动态更新其 checked 属性。 AFAICT,checked 属性 是当输入被选中时发生变化的。

    • 此外,原生&lt;input type="radio"&gt; 输入只会在它们被选中时触发它们的changeinput 事件,而不是在它们被取消选中时触发。 Polymer 依靠事件来触发数据绑定等属性效果;这意味着只有当输入上的checked 属性从false 更改为true 时,才会处理向上的数据绑定(从输入到自定义元素)。实际上,一旦ratings[n].checked 变为真,它就永远不会变为假,因为 Polymer 无法知道这已发生。

      顺便说一下,要对原生 HTML 元素执行双向绑定,you would also need to include an annotation for the event that the radio input fires when it is selected。因此,如果您确实想捕获选择时的更改,则类似于checked="{{item.checked::change}}"

    几个选项:

    • paper-radio-group 中使用paper-radio-buttons 而不是本机&lt;input&gt;s。这些元素在双向数据绑定方面表现良好。

    • 在检查新项目时侦听更改,并手动将先前选择的项目的 ratings[n].checked 更新为 false

    关于您的代码的更多信息

    • (我认为这与您当前的问题无关,但它有助于避免将来出现问题)在初始化 Polymer 元素中的对象或数组属性的默认值时,remember to use a function 以便每个元素实例获得自己唯一的数组或对象。例如:

      ratings: { type: Array, value: function(){ return [ { id: 1, checked: true }, { id: 2, checked: false } ]; } }

    • 通常我认为,您不会想要更改无线电输入的 。按照惯例,当提交包含无线电输入组的&lt;form&gt; 时,当前为checked 的无线电输入上的value 将包含在表单数据中,而其他无线电输入值将被忽略。 Here's an example on 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
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 2016-12-19
      相关资源
      最近更新 更多