Ember的notifyPropertyChange()不会触发包装组件

时间:2015-10-28 17:21:18

标签: javascript ember.js

这是一个简化的例子,但很好地证明了我的问题。我有一个PIN输入,带有数字按钮(1,2,3,4)。我的按钮上的操作应设置一个属性pinValue,该属性将传递到包装的组件pin-input中。所以这就是我的代码:

参见示例 http://ember-twiddle.com/38bd66b63e6745f2ea0d

固定-entry.hbs

{{pin-input pinValue=pinValue}}
{{#each numbers as |num|}}
    <button {{action "addNumber" num}}>{{num}}</button>
{{/each}}

固定-entry.js

pinValue: null,
numbers: [1, 2, 3, 4],
actions: {
    addNumber: function (number) {
        this.set('pinValue', number);
        this.notifyPropertyChange('pinValue');
    }
}

固定-input.hbs

<input type=text value={{value}}>

固定-input.js

value: null,
pinValue: null,

onInsertAddObserver: function() {
    // trying to manually subscribe to pinValue here.
    // * from stackOverflow answer
    var controller = this.get('targetObject');
    controller.addObserver('pinValue', this, this.onDataChange)
}.on('didInsertElement'),

onDidChangeInput: function() {
    var current = this.$('input').val();
    this.set('value', current + this.get('pinValue'));
}.observes('pinValue')

问题是当尝试重复输入重复的数字时(例如1233将在123处停止)。我似乎无法强制更改属性以便onDidChangeInput将触发。 addObserver方法来自另一个帖子*。

*从这里采取的一些想法但对我没有帮助:EmberJS notifyPropertyChange not making it to observer?

2 个答案:

答案 0 :(得分:1)

由于数据下降和操作上升

我会选择这样的东西。

{{pin-input pinCode=current}} // Explaining it later 
{{#each numbers as |num|}}
    {{pin-number nr=num numberChanged="numberChanged"}}
{{/each}}

销number.js

actions: {
    addNumber: function (number) {
        this.sendAction('numberChanged', number); // To the controller
    }
}

controller.js

   actions: {

     numberChanged: function(newNr) {
       var current = this.get('current');

       if(Ember.isNone(current) || current.length >= 4) { 
          this.set('current', newNr);
       } else {
          this.set('current', this.get('current') + "" + newNr);
       }

   }

现在我们将电流绑定到 引脚输入

{{pin-input pinCode=current}}

答案 1 :(得分:1)

我最终用一个简单但不优雅的解决方案解决了这个问题。出于某种原因,即使将属性传递给另一个组件,如果值未更改,主组件属性中的更改也不会导致包装组件中的观察者触发。即使你打电话给notifyPropertyChange(),他们仍然不会开火。我想出的真正简单的解决方案是:

See the twiddle here(只是下面的重要部分)

固定-entry.js

pinValue: null,
_cachedValue: null,

actions: {
    addNumber: function (number) {
        this.set('pinValue', number);
        // just cache the value and if you detect a duplicate
        // then force the property to update
        if (this.get('_cachedValue') === number) {
            this.notifyPropertyChange('pinValue');
        }
        this.set('_cachedValue', number);
    }
}

固定-input.js

// this is how you have to subscribe.
onInsertAddObserver: function() {
    var c = this.get('targetObject');
    c.addObserver('pinValue', this, this._onChange)
}.on('didInsertElement'),

有人认为这是离开的吗?