聚合:在不通知观察者的情况下更改观察者属性的值

时间:2016-10-31 13:49:36

标签: event-handling polymer polymer-1.0 observers

该方案在某些条件下阻止了价值的变化。为此,我发现 observer 函数本身是检查更改的最佳位置。

但是,在观察者中更改属性的值会导致观察者再次变成黑洞。

properties: {
        foobar: {
                type: String,
                observer: 'foobarChanged'
        }
},

foobarChanged: function(oldValue, newValue) {
        if(!matchesCertainCondition(newValue))
                this.foobar = oldValue;
}

但是,我无法提出直接的解决方案。在Polymer 1.x中有没有办法做到这一点?

为什么他们应该在观察者本身内向观察值发射变化事件?

也欢迎变通办法!

2 个答案:

答案 0 :(得分:1)

可以使用基于另一个公共属性的computed property来解决此问题,而不是使用观察者。计算属性将检测对公共属性的所有更改,验证输入值,并可选地返回不同的值。

在此示例中,计算属性_index计算基于index的值,最大值为100

// template
<div>[[_index]]</div>

// script
Polymer({
  is: 'x-foo',
  properties: {
    index: Number,
    _index: {
      computed: '_computeIndex(index)'
    }
  },
  _computeIndex: function(index) {
    return Math.min(index, 100);
  }
);

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties: {
      index: Number,
      _index: {
        computed: '_computeIndex(index)'
      }
    },
    _computeIndex: function(index) {
      return Math.min(index, 100);
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo index="200"></x-foo>

  <dom-module id="x-foo">
    <template>
      <div>index: [[index]]</div>
      <div>_index: [[_index]]</div>
    </template>
  </dom-module>
</body>

codepen

答案 1 :(得分:1)

如果你需要它来处理双向数据绑定,我想出了一个(相当粗略的)解决方法。只需将您的属性设为一个对象,使用一个布尔键值表示切换或标记,告诉您它是否被内部或外部事件更改。这类似于其他回答者的评论,但是是异步安全的。 这看起来如下所示:

properties: {
  foobar: {
    type: Object,
    notify: true,
    value: {
      value: 'blah',
      internalToggle: false
    },
    observer: '_foobarChanged'
  }
}

...

_foobarChanged: function(oldfoobar, newfoobar) {
    if (oldfoobar.internalToggle != newfoobar.internalToggle) {
      return
    }
    if (oldfoobar.value != newfoobar.value) {
      // Do stuff
      if(!matchesCertainCondition(newfoobar.value))
        this.foobar = {value: oldfoobar.value, 
                       internalToggle: !oldfoobar.internalToggle};
      }
    }  
}

总是如此地狱,但它确实有效。老实说,在这一点上,几乎值得放弃聚合物的双向绑定,只是分裂成多个属性。