数据更改时如何更新 polymer 1.x 中的 DOM?

How do I update the DOM in polymer 1.x when data is changed?

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

我有两个视图(表单视图和显示视图),我想在另一个名为数据存储的元素中的对象中共享 "stored" 的数据。

这是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”函数,但更改不会在显示视图上更新。

但是,如果您在对 "form-view" 进行更改后单击显示视图上的 "get data" 按钮,您将看到更改显示在 formData 对象上(在 console.log) 只是不在视图中。我什至尝试使用:

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

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

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

谢谢!

Polymer implements the mediator pattern, where a host element manages data flow between itself and its local DOM nodes.

When two elements are connected with a data binding, data changes can flow downward, from host to target, upward, from target to host, or both ways.

When two elements in the local DOM are bound to the same property data appears to flow from one element to the other, but this flow is mediated by the host. A change made by one element propagates up to the host, then the host propagates the change down to the second element.

因此,在上面的代码中,您试图使数据在三个目标或子元素之间流动,即在 data-storeform-viewdisplay-view 之间。这就是数据未在 display-view 中呈现的原因。如果 data-store 将 属性 存储在本地存储中并且其他元素使用该存储来提取 属性,它就会显示。这是完成您正在寻找的事情的一种方式。

另一种方法是从宿主元素传递 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