2015-04-07 2 views
0

У меня есть 3 разных модели крепежа, как показано ниже.EmberJS - hasMany Светильники Модель Пустое значение

var Room = DS.Model.extend({ 
     title: DS.attr('string'), 
     categories: DS.hasMany('Category', { async: true }), 
     isSelected: DS.attr('boolean') 
}); 
var Category = DS.Model.extend({ 
    title: DS.attr('string'), 
    room: DS.belongsTo('Room', {async: true }), 
    materials: DS.hasMany('Material', { async: true }), 
    isSelected: DS.attr('boolean') 
}); 
var Material = DS.Model.extend({ 
    title: DS.attr('string'), 
    category: DS.belongsTo('Category', {async: true}), 
    isSelected: DS.attr('boolean') 
}); 

Я нахожу, когда пытаюсь просмотреть содержимое в модели материалов, оно пустое. В мой контроллер я разоблачить материалы, делая это:

currentMaterials: function() { 
    var room = this.filterBy('isSelected', true).get('firstObject'); 
    var categories = room.get('categories'); 
    var selectedCategory = categories.get('firstObject'); 
    var material = selectedCategory.get('materials'); 
    return material; 

}.property('@each.isSelected') 

Однако, когда я пытаюсь получить доступ currentMaterials значение равно нулю. Я ТОЛЬКО могу получить доступ к своим значениям, если я сначала получаю доступ к Номерам/категориям, используя цикл {{#each}. Как ни странно, когда я делаю {{#each}}, я могу получить доступ к значениям в currentMaterials.

Кто-нибудь понимает, почему?

ответ

1

Это связано с фактом существования обещаний. Отношение categories равно асинхронному, что означает, что он отсутствует изначально, и данные ember-data должны извлекать его, если это необходимо. Однако для получения данных требуется время, поэтому данные ember-data возвращают обещание от этого: var categories = room.get('categories'). После этого обещания вы сначала получите firstObject, который не существует для обещания (имеет значение null), и вы получаете связь materials от этого нуля. Он просто равен нулю.

Тем не менее, шаблоны ember являются умными, и если вы нанесете на них each, они знают, что эти отношения необходимы и заставляют данные ember-data извлекать эти данные.

Что вы можете сделать? Если вам нужны эти данные для выполнения задания по конкретным страницам, вы должны убедиться, что у вас есть к нему доступ, прежде чем показывать страницу пользователю, поэтому в крючке модели. Вы можете использовать Ember.RSVP сделать несколько выборки вызовов и настроить их в контроллере:

model: function() { 
    data = 
    room: store.find("room") 
    categories: store.find("category) 
    materials: store.find("material") 

    return Ember.RSVP.hash(data) 
} 

Однако, обратите внимание, что он будет получать all материалы и т.д. Если вам нужны только те, которые подключены к вашей модели , вы должны рассмотреть возможность ускорения сбора данных с помощью side loading. Если вы используете светильники, это не сработает.

Последнее, что я могу думать о том, что вычисляемое свойство представляет собой метод, который будет извлекать данные, но устанавливает их для другой переменной. Вы можете использовать какой-либо флаг для информирования приложения, когда данные готовы:

currentMaterials: function() { 
    var room = this.filterBy('isSelected', true).get('firstObject'); 
    room.get('categories').then(function(categories) { 
    return categories.get('firstObject').get('materials'); 
    }).then(function(materials) { 
    // here you have your materials 
    // you can pass _this to that method and set these materials 
    // on some kind of controller property (e.g. materialsChosen) 
    // and use a flag like setting 'is Fetching' on the start of this 
    // computed property and setting down right here 
    }); 
}.property('@each.isSelected') 
+0

Отличное объяснение, чтобы описать очень сложную конфигурацию. Спасибо за вашу помощь Jakub – netvampire

Смежные вопросы