2015-10-28 3 views
0

Это упрощенный пример, но хорошо демонстрирует мою проблему. У меня есть ввод PIN-кода с кнопками для цифр (1, 2, 3, 4). Действие на моих кнопках должно установить свойство pinValue, которое передается в обернутый компонент pin-input. Так это то, что мой код выглядит следующим образом:Уведомление EmberPropertyChange() не срабатывает для наблюдателей обернутого компонента

Смотрите пример: 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?

+0

Вам не нужно «notifyPropertyChange» или любой из наблюдателей. – runspired

+0

Вот рабочий принцип: http://ember-twiddle.com/9c1517b37f44635a17c7 – runspired

+0

Единственная проблема заключается в том, что мерцание сбрасывает позицию курсора после обновления значения, вы можете исправить это, используя этот компонент: http: // ember-twiddle .com/2d7246875098d0dbb4a4 – runspired

ответ

0

Я в конечном итоге решил его с помощью простого, хотя и неэлегантного, решения. По какой-то причине, даже если вы передаете свойство другому компоненту, изменения в свойстве основного компонента не приводят к тому, что наблюдатели в обернутом компоненте загорятся, если значение не изменилось. Даже если вы звоните 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); 
    } 
} 

пин-вход.JS

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

Любой думаю, что это далеко?

+0

Наблюдатели - плохая практика в целом, я предоставил ua приличное решение, но что за черт. Просто уточнить, почему: https://www.youtube.com/watch?v=vvZEddrClAQ –

+0

да, я использую их экономно, но они не так злы, как все говорят. Я попробовал ваш пример, и это не сработало. Если вы вставляете код в twiddle, чтобы я мог видеть, что он работает, тогда я помету ваш ответ как правильный. – Jeff

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}}