【问题标题】:Observe changes for an object in Polymer JS在 Polymer JS 中观察对象的变化
【发布时间】:2017-01-09 18:20:31
【问题描述】:

我有一个带有模型对象的元素,我想像这样观察:

<polymer-element name="note-editor" attributes="noteTitle noteText noteSlug">
  <template>
    <input type="text" value="{{ model.title }}">
    <textarea value="{{ model.text }}"></textarea>
    <note-ajax-button url="/api/notes/" method="POST" model="{{model}}">Create</note-ajax-button>
  </template>

  <script>
    Polymer('note-editor', {
      attached: function() {
        this.model = {
          title: this.noteTitle,
          text: this.noteText,
          slug: this.noteSlug
        }
      },
    });
  </script>
</polymer-element>

我想观察模型的变化,但显然不可能在元素中使用 modelChanged 回调,也不能在 note-ajax-button 元素中使用。怎么了?我该怎么做?

我试过单独观察这些字段,但它一点也不干净。您在那里看到的按钮元素的状态应该根据模型状态而改变,所以我需要观察对象的变化,而不是属性的变化。 谢谢!

【问题讨论】:

    标签: polymer


    【解决方案1】:

    要观察对象中的路径,您需要使用observe 块:

    Polymer('x-element', {
      observe: {
        'model.title': 'modelUpdated',
        'model.text': 'modelUpdated',
        'model.slug': 'modelUpdated'
      },
      ready: function() {
        this.model = {
          title: this.noteTitle,
          text: this.noteText,
          slug: this.noteSlug
        };
      },
      modelUpdated: function(oldValue, newValue) {
        var value = Path.get('model.title').getValueFrom(this);
        // newValue == value == this.model.title
      }
    });
    

    http://www.polymer-project.org/docs/polymer/polymer.html#observeblock

    【讨论】:

    • 谢谢!这就是我尝试过的,但是如果不指定路径就不可能观察到完整的对象?例如,当我添加一个新属性时,我必须将它添加到带有该提案的观察块中,不是吗?
    • Object.observe() 只允许您观察顶级属性。例如,如果您更改 x = {a:{b:{c:'foo;}}} 中的属性 co.O() 不会观察到该更改。 observe-js,位于 o.O() 之上的 Polymer 库增加了对观察对象深度变化的支持。
    • 观察是否支持任何类型的通配符?像'model.*'或'model[*].value'?这在 'model' 是一个数组时特别有用。
    • 数组/对象观察:github.com/polymer/observe-js。这是一个技巧,在模板重复中,通过对象数组,如果您将过滤器添加为:{{obj.property | modelUpdated}} 如果将对每个属性更改做出反应。 plnkr.co/edit/zpiOIMOgDzdmaWpkS7Vd?p=preview
    【解决方案2】:

    或者你可以为你的模型添加一个额外的属性,例如'refresh'(布尔值),每次你修改一些内部值时,也可以通过设置refresh = !refresh来修改它,那么你可以只观察一个属性而不是很多。当您的模型包含多个嵌套属性时,这是一个很好的例子。

    Polymer('x-element', {
      observe: {
        'model.refresh': 'modelUpdated'
      },
      ready: function() {
        this.model = {
          title: this.noteTitle,
          text: this.noteText,
          slug: this.noteSlug,
          refresh: false
        };
      },
      modelUpdated: function(oldValue, newValue) {
        var value = Path.get('model.title').getValueFrom(this);
      },
      buttonClicked: function(e) {
        this.model.title = 'Title';
        this.model.text = 'Text';
        this.model.slug = 'Slug';
        this.model.refresh = !this.model.refresh;
      }
    });
    

    【讨论】:

      【解决方案3】:

      在这种情况下我所做的是使用 * 字符来观察我的数组中的任何属性变化,这里是我的 JSON 对象的示例:

      {
          "config": { 
              "myProperty":"configuraiont1",
              "options": [{"image": "" }, { "image": ""}]
           }
      };
      

      我创建了一个方法 _myFunctionChanged 并作为参数传递 config.options.* 然后在数组 options 中观察到每个属性函数_myFunctionChanged

      Polymer({ 
       observers: ['_myFunctionChanged(config.options.*)'] 
      });
      

      您可以对对象使用相同的模式,而不是使用像 config.options 这样的数组。 您只需观察 config.

      【讨论】:

        猜你喜欢
        • 2021-02-10
        • 1970-01-01
        • 2018-11-18
        • 2017-09-07
        • 2017-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多