[英]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.