我很贪图开发并需要帮助来处理这类任务:
目前我正在使用embers-cli app中的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>
My Ingredients-Controller看起来像这样:
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')
});
承诺中的控制台日志很好,但我无法将评估的承诺返回给模板:
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: }
当我删除promise并只使用this.get('model')时,计算出的数组中充满了未定义的值,导致模型似乎没有完全加载。 如何以这种方式解决此问题以处理异步模型数据? 谢谢!
答案 0 :(得分:0)
我的代码遇到了类似的问题,它通常涉及为计算属性设置错误的依赖项。
根据您的代码,我会说您的groupsIngredients:属性可能应该符合以下几行:
.property('@each.groupTag')
一旦设置正确,您应该能够从控制器中删除承诺,因为它应该在履行承诺后自动更新。
答案 1 :(得分:0)
您不需要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)
Here是groupBy
作为计算属性的实现,您可能可以对其进行调整,如果有效则可以让您简单地执行
groupedIngredients: Ember.computed.groupBy('groupTag')