[英]Got stuck with Ember.js handing over computed property to template
我是炭燼開發的新手,需要幫助來處理此類任務:
目前,我正在使用ember-cli應用程序中的Fixtures。 有關的兩個模型是:
var Recipe = DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string'),
ingredients: DS.hasMany('ingredients',{async: true}),
recipeCategory: DS.belongsTo('recipeCategory', {async: true})
});
var Ingredient = DS.Model.extend({
title: DS.attr('string'),
portion: DS.attr('string'),
groupTag: DS.attr('string'),
recipe: DS.belongsTo('recipe')
});
雖然列出通過嵌套路線調用的特定食譜的所有成分(也已排序)沒有問題,
this.resource('recipes',function(){
this.resource('recipe', {path: '/:recipe_id'});
});
按groupTag分組成分時遇到大問題。 分組的邏輯不是問題,但是我遇到了競爭條件,即訪問控制器中用於計算屬性的模型,或者在嘗試處理模板中的Promise時遇到框架錯誤。
以下是相關模板:
//recipe.hbs
<strong>{{recipeCategory.title}}</strong>
<h3>{{title}}</h3>
{{render 'ingredients' ingredients}}
//ingredients.hbs
<strong>Zutaten</strong>
<ul>
{{#each groupedIngredients}}
<li>{{group}}
<ul>
{{#each items}}
<li>{{portion}} {{title}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
我的原料控制器看起來像這樣:
var IngredientsController = Ember.ArrayController.extend({
sortProperties: ['title'],
sortedIngredients: Ember.computed.sort('model', 'sortProperties'),
groupedIngredients: function(){
return this.get('model').then(function(ingredients){
var groupTags = ingredients.mapBy('groupTag').uniq();
var groupedIngredients = groupTags.map(function(gtag){
return {
group: gtag,
items: ingredients.map(function(item){
if ( item.get('groupTag') == gtag){
return item;
}
}).compact()
};
});
console.log(groupedIngredients);
return groupedIngredients;
});
}.property('model')
});
Promise中的控制台日志很好,但是我無法將Promise評估返回給模板:
Uncaught Error: Assertion Failed: The value that #each loops over must be an Array. You passed {_id: 158, _label: undefined, _state: undefined, _result: undefined, _subscribers: }
當我刪除承諾並僅在this.get('model')上工作時,計算數組充滿了未定義的值,導致模型似乎未完全加載。 如何解決此問題以這種方式處理異步模型數據? 謝謝!
我的代碼也遇到類似的問題,通常會處理為計算屬性設置錯誤的依賴關系。
根據您的代碼,我會說您的groupedIngredients:屬性應該遵循以下原則:
.property('@each.groupTag')
正確設置后,您應該能夠從控制器中刪除承諾,因為一旦實現承諾,它就會自動更新。
你不需要做你計算的then
掛的get('model')
在代碼中達到這一點時,模型已經解析完畢,可以開始使用了。 路由器已經確保在繼續進行之前解決了模型承諾。
因此:
groupedIngredients: function(){
var ingredients = this.get('model');
var groupTags = ingredients.mapBy('groupTag').uniq();
var groupedIngredients = groupTags.map(function(gtag){
return {
group: gtag,
items: ingredients.map(function(item){
if ( item.get('groupTag') == gtag){
return item;
}
}).compact()
};
});
console.log(groupedIngredients);
return groupedIngredients;
}.property('@each.groupTag')
為了避免compact
,只需切換到使用filter
:
items: ingredients.filter(function(item){
return item.get('groupTag') === gtag;
}
這與
items: ingredients.filterBy('groupTag', gtag)
這是groupBy
作為計算屬性的實現,您可能可以適應它,並且如果它可以工作,則您可以簡單地執行
groupedIngredients: Ember.computed.groupBy('groupTag')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.