2015-04-07 22 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') 
}); 

我發現當我嘗試查看Materials模型內部的內容時,它是空白的。在我的控制器我做這個揭露材料:

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值爲null。如果我第一次使用{{#each}循環訪問房間/類別,我只能訪問它的值。奇怪的是,一旦我做{{#each}},我可以訪問currentMaterials中的值。

有沒有人知道爲什麼?

回答

1

這是由於承諾存在的事實。你的categories關係是異步的,這意味着它不是最初出現的,並且如果需要的話,它應該獲取它。但是,獲取數據需要一些時間,因此ember-data將返回一個承諾:var categories = room.get('categories')。在承諾之後,你首先從它得到firstObject,這對於諾言是不存在的(是空的),並且你從那個null得到materials關係。它簡直是空的。

然而,燼模板很聰明,如果你把each放在它們上面,他們知道這些關係是必需的,並使得燼數據獲取這些數據。

你可以做什麼?如果您需要此數據來執行頁面特定的作業,則應在向用戶顯示頁面之前確保您有權訪問它 - 因此在模型鉤子中。您可以使用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