Использование computed'ов c сеттерами внутри Ember.Component
Опубликовано Пт. 31 Март 2017 в Development
При использовании сеттеров в Ember.Component
я сталкнулся с нетрививальным поведеним ember,
при передаче параметеров в компонент.
Смотри, например у тебя есть компонент:
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend( {
required: computed( function() {
alert( 'No overridden!' );
} ),
overridden: computed( 'required', {
get( key ) {
this.get( '_inner' );
},
set( key, value ) {
this.set( '_inner', `${value}_${this.get( 'required' )}` );
}
} ),
displayValue: computed.alias( 'overridden' )
} );
И вот так ты его используешь:
{{side-effect
overridden='foo'
required='bar'}}
Как думаешь, вылетит alert или нет? Можешь проверить себя на ember-twiddle.
А вот для меня было неожиданно, что вылетит.
Причём, если поменять порядок параметров при передаче в компонет, то не вылетит:
{{side-effect
required='bar'
overridden='foo'}}
Помнить о порядке для именнованых параметров это так себе идея, поэтому будет радикально рефакторить, а точне полностью избавляться от this.set
.
Для этого вынесем второй аргумент this.set( ... )
в отдельный Ember.computed
:
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend( {
required: computed( function() {
alert( 'No overridden!' );
} ),
displayValue: computed( 'required', 'overridden', function() {
return `${this.get( 'overridden' )}_${this.get( 'required' )}`;
} )
} );
И теперь все работает как-надо!
Проверить, если ли у тебя похожий код можно с помощью линтера ember-best-practices, для этого даже отдельное правило есть: no-side-effect-cp
Ну и на будущее - не используй Ember.set
в внутри computed, это легко может привести к эксепшену