如何更改数据时如何更新聚合物1.x中的DOM?

时间:2017-08-22 21:54:24

标签: javascript polymer

我是Polymer的新手,来自Angular背景,使用服务在组件之间共享数据。

我有两个视图(窗体视图和显示视图),我想分享“存储”在另一个名为数据存储的元素中的对象的数据。

以下是plunker

形式视

<dom-module id="form-view">

      <template>

        <style>
          :host {
            display: inline-block;
          }
        </style>

        <h1>Form View</h1>
        <label for="form-name">Name</label>
        <input id="form-name" value="{{formData.name::change}}">
        <label for="form-city">City</label>
        <input id="form-city" value="{{formData.city::change}}">

        <data-store form-data="{{formData}}"></data-store>
      </template>



      <script>
      Polymer({
        is: 'form-view',
        ready: function() {
          console.log("FORM VIEW", this.formData);
        },
        properties: {
          formData: {
            type: Object
          }
        }
      });
      </script>

    </dom-module>

显示视
        

      <template>

        <style>
          :host {
            display: inline-block;
          }
        </style>
        <h1>Display View</h1>
        <h4>Name: {{formData.name}}</h4>
        <h4>City: {{formData.city}}</h4>
        <button id="getData">Get Data</button>
        <data-store form-data="{{formData}}"></data-store>
      </template>

      <script>
      Polymer({
        is: 'display-view',
        properties: {
          formData: {
            type: Object
          }
        },
        ready: function(){
          var that = this;
          console.log('display view', this.formData);

          this.$.getData.addEventListener('click', function(evt) {
            console.log("Form Data from store", that.formData);
            that.set('formData.name', that.formData.name);
            that.set('formData.city', that.formData.city);
          })
        }
      });
      </script>

    </dom-module>

数据存储

    <dom-module id="data-store">

      <template>

        <style>
          :host {
            display: inline-block;
          }
        </style>

      </template>

      <script>
      Polymer({
        is: 'data-store',
        properties: {
          formData: {
            type: Object,
            notify: true,
            value: {
              name: 'Hello',
              city: 'World'
            }
         }
        },
        observers: ['_dataChanged(formData.*)'],
        _dataChanged: function(change) {
          console.log("DATA CHANGED", change);
          console.log("Form Data", this.formData);
        }

      });
      </script>

    </dom-module>

每当我更改窗体视图上的输入时,我基本上都希望更新显示视图。

如果您打开plunker,您会看到表单视图和显示视图都显示数据存储中名称和城市的原始值。

我如何约束他们:

<data-store form-data="{{formData}}"></data-store>

当我更改其中一个输入时,数据存储中的观察者会触发'_dataChanged'函数,但更改不会在显示视图上更新。

但是,如果在“窗体视图”上进行更改后单击显示视图上的“获取数据”按钮,您将看到更改显示在formData对象上(在console.log中)只是不在视图中。我甚至试图使用:

  this.set('formData.name', this.formData.name);

即使这样也不会更新显示视图上的值。

有人可以帮助我理解为什么我的数据没有被更新,以及如何在一个视图上更新输入并在绑定到同一个对象的所有其他视图上更改它?

谢谢!

1 个答案:

答案 0 :(得分:1)

  

Polymer实现主机元素管理的mediator pattern   本身与其本地DOM节点之间的数据流。

     

当两个元素与数据绑定连接时,数据更改可以   流向下,从主机到目标,向上,从目标到主机,或者   两种方式。

     

当本地DOM中的两个元素绑定到相同的属性数据时   似乎从一个元素流向另一个元素,但这个流程是   由主持人介导。由一个元素进行的更改会传播到   主机,然后主机将更改传播到第二个   元件。

因此,在上面的代码中,您尝试在三个目标或子元素之间进行数据流动,即data-storeform-viewdisplay-view之间。这就是数据未在display-view中呈现的原因。如果data-store已将属性存储在localstorage中,并且其他元素使用该存储来提取该属性,则会显示它。这是做你想要的事情的一种方式。

另一种方法是从主机元素传递formData,即从parent-view传递。你可以这样做:

<data-store form-data="{{formData}}"></data-store>
<iron-pages selected="[[routeName]]" attr-for-selected="name">
  <form-view form-data="{{formData}}" name="form"></form-view>
  <display-view form-data="{{formData}}" name="display"></display-view>
</iron-pages>

检查plnkr:https://plnkr.co/edit/KLw8G04qVPVPmderLlzd?p=preview