Как бороться с асинхронными свойствами в Ember, когда мне нужно блокировать вызовы?
Мы использовали модель с hasMany со встроенными дочерними элементами. Это было хорошо, так что всякий раз, когда я вызывал model.get('children'), все просто работало.
Теперь мы изменили это свойство children на async:true, и я не могу найти надлежащую документацию о том, как вы должны это делать.
Позвольте привести пример. Я буду использовать упрощенный json для представления своей установки Ember, просто для простоты.
Скажем, у меня есть такая модель:
model:{
hasMany: {children: {async: true} },
isActive: boolean
}
Скажем, у меня есть такой шаблон:
{{#if lastChildIsActive}}
<p>I'm the last one!</p>
{{/if}}
И у меня есть контроллер:
controller:{
lastChildIsActive: function(){
return this.get('model').get('children').get('lastObject').get('isActive')
}
}
Итак, с этой настройкой, когда использовался async: false, все просто работало.
Но теперь, с async true, этот вызов в контроллере для.get('children') SOMETIMES просто ничего не возвращает, потому что я полагаю, что он асинхронный.
Теперь я могу использовать обещания и изменить свой контроллер на это:
controller:{
lastChildIsActive: function(){
this.get('model').get('children').then(function(children){
return children.get('lastObject').get('isActive');
});
}
}
Проблема со вторым рефакторингом заключается в том, что я больше не возвращаю значение isActive, теперь я возвращаю объект обещания.
Но шаблон не хочет обещания, ему нужно возвращаемое значение.
Итак, как я могу убедиться, что асинхронность загружена, и в то же время я могу вернуть фактический результат вызова вместо обещания?
2 ответа
Используя view и didInsertElement, вы можете получить дочерние элементы родительского элемента, а затем обновить атрибут на контроллере, который появится в вашем шаблоне.
App.IndexView = Ember.View.extend({
didInsertElement: function() {
controller = this.get('controller');
controller.get('model').get('children').then(function(children){
active = children.get('lastObject').get('active');
controller.set('lastChildIsActive', active);
});
}
});
Смотрите эту скрипку: http://jsfiddle.net/f9DAc/2/
Вы должны использовать наблюдателя, чтобы слушать изменения у детей. См. Изменения, которые я сделал в lastChildIsActive
метод ниже. Поскольку children - это тип массива, я слушаю слова "children. @ Each". Всякий раз, когда есть изменение в "childern", lastChildIsActive
будет обновляться автоматически.
controller:{
lastChildIsActive: function(){
return this.get('model').get('children').get('lastObject').get('isActive')
}.property('children.@each')
}