Как бороться с асинхронными свойствами в 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')
}
Другие вопросы по тегам