【问题标题】:How to notify array mutation to parent component in polymer 3如何将数组突变通知给聚合物 3 中的父组件
【发布时间】:2019-07-03 02:03:30
【问题描述】:

我有 2 个组件使用相同的数组绑定,例如:

{
 title: "food",
 data : ["data1", "data2", "data3"]
}

标题在父组件上,数据从父组件绑定到子组件到子组件与数组一起使用。

当我删除一个数组数据元素通知给父组件时,我该怎么办?

这里是例子。

在示例中,我有一个带有绑定数组的子项和一种删除数组元素并通知的方法。并且父组件有一个名为 arrayChanges 的观察者。

如果代码有效,父组件必须知道子数组的长度,但它不起作用。

<script type='module'>
  import {PolymerElement, html} from 'https://unpkg.com/@polymer/polymer/polymer-element.js?module';
  import {} from 'https://unpkg.com/@polymer/polymer@3.1.0/lib/elements/dom-repeat.js?module';

  class ParentComp extends PolymerElement {
    static get properties() {
      return {
        myArr: {
          type: Array,
          observer: "arrayChanges"
        },
        changes: {
          type: String
        }
      };
    }
    static get template() {
      return html`
        <div>[[myArr.title]]</div>
        <children-comp data='[[myArr.data]]'></children-comp>
        <div>[[changes]]</div>
      `;
    }
    ready(){
      super.ready();
      this.myArr = {
        title : "My component",
        data : [
          {titulo: "titulo1", comment : "im comment number 1"},
          {titulo: "titulo2", comment : "im comment number 2"}
        ]
      }
    }
    arrayChanges(){
      this.changes = "Array length : "+this.myArr.data.length;
      console.log("the Array has been changed");

    }

  }

  class ChildrenComp extends PolymerElement {
    static get properties() {
      return {
        data: {
          type: Array,
          notify: true
        }
      };
    }
    static get template() {
      return html`
      <ul>
        <dom-repeat items='[[data]]' >
          <template>
            <li>
              [[index]] )
              [[item.titulo]]
              [[item.comment]]
              <button data-index$='[[index]]' on-click='handle_button'>Borrar</button>
              <hr>            
            </li>
          </template>
        </dom-repeat>
      </ul>      
      `;
    }
    handle_button(e){
      var index = e.currentTarget.dataset.index;
      this.notifyPath("data");
      this.splice("data", index, 1);
    }


  }
  customElements.define('children-comp', ChildrenComp);
  customElements.define('parent-comp', ParentComp);


</script>
<parent-comp></parent-comp>

【问题讨论】:

    标签: javascript arrays polymer observers polymer-3.x


    【解决方案1】:

    父组件只会处理two-way bindings 中的更改通知(使用大括号)。您的数据绑定错误地使用了单向绑定(方括号)。

    <children-comp data='[[myArr.data]]'></children-comp>
                         ^^          ^^ square brackets: one-way binding
    <children-comp data='{{myArr.data}}'></children-comp>
                         ^^          ^^ curly brackets: two-way binding
    

    还要注意简单的观察者(在myArr-property 声明中指定)不检测数组突变。您应该改用complex observer。您可以观察数据/长度变化和/或array mutations:

    static get properties() {
      return {
        myArr: {
          // type: Array, // DON'T DO THIS (myArr is actually an object)
          type: Object,
          // observer: 'arrayChanges'  // DON'T DO THIS (doesn't detect array splices)
        }
      }
    }
    
    static get observers() {
      return [
        'arrayChanges(myArr.data, myArr.data.length)',  // observe data/length changes
        'arraySplices(myArr.data.splices)',             // observe array mutations
      ]
    }
    
    arrayChanges(myArrData, myArrDataLength) {
      console.log({
        myArrData,
        myArrDataLength
      })
    }
    
    arraySplices(change) {
      if (change) {
        for (const s of change.indexSplices) {
          console.log({
            sliceIndex: s.index,
            removedItems: s.removed,
            addedItems: s.addedCount && s.object.slice(s.index, s.index + s.addedCount)
          })
        }
      }
    }
    

    <html>
    <head>
      <script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    </head>
    <body>
      <script type='module'>
      import {PolymerElement, html} from 'https://unpkg.com/@polymer/polymer/polymer-element.js?module';
      import {} from 'https://unpkg.com/@polymer/polymer@3.1.0/lib/elements/dom-repeat.js?module';
    
      class ParentComp extends PolymerElement {
        static get properties() {
          return {
            myArr: {
              type: Array,
            },
            changes: {
              type: String
            }
          };
        }
    
        static get observers() {
          return [
          'arrayChanges(myArr.data, myArr.data.length)',
          'arraySplices(myArr.data.splices)',
          ]
        }
    
        static get template() {
          return html`
            <div>[[myArr.title]]</div>
            <children-comp data='{{myArr.data}}'></children-comp>
            <div>{{changes}}</div>
          `;
        }
        ready(){
          super.ready();
          this.myArr = {
            title : "My component",
            data : [
              {titulo: "titulo1", comment : "im comment number 1"},
              {titulo: "titulo2", comment : "im comment number 2"}
            ]
          }
        }
    
        arrayChanges(myArr, myArrLength){
          this.changes = "Array length : " + myArrLength;
          console.log("the Array has been changed", myArr);
        }
    
        arraySplices(change) {
          if (change) {
            for (const s of change.indexSplices) {
              console.log({
                sliceIndex: s.index,
                removedItems: s.removed,
                addedItems: s.addedCount && s.object.slice(s.index, s.index + s.addedCount)
              })
            }
          }
        }
      }
    
      class ChildrenComp extends PolymerElement {
        static get properties() {
          return {
            data: {
              type: Array,
              notify: true
            }
          };
        }
        static get template() {
          return html`
          <ul>
            <dom-repeat items='[[data]]' >
              <template>
                <li>
                  [[index]] )
                  [[item.titulo]]
                  [[item.comment]]
                  <button data-index$='[[index]]' on-click='handle_button'>Borrar</button>
                  <hr>
                </li>
              </template>
            </dom-repeat>
          </ul>
          `;
        }
        handle_button(e){
          var index = e.currentTarget.dataset.index;
          this.notifyPath("data");
          this.splice("data", index, 1);
        }
    
      }
      customElements.define('children-comp', ChildrenComp);
      customElements.define('parent-comp', ParentComp);
    </script>
    
    <parent-comp></parent-comp>
    
    </body>
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 2015-10-13
      相关资源
      最近更新 更多