【问题标题】:Got stuck with Ember.js handing over computed property to template卡住了 Ember.js 将计算属性移交给模板
【发布时间】:2014-11-05 19:32:37
【问题描述】:

我是 ember 开发的新手,在处理此类任务时需要帮助:

目前我正在使用 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') 时,计算的数组中充满了未定义的值,导致模型似乎没有完全加载。 如何解决此问题以以这种方式处理异步模型数据? 谢谢!

【问题讨论】:

    标签: javascript ember.js controller


    【解决方案1】:

    您不需要在 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)
    

    HeregroupBy 的一个实现,作为计算属性,您可能能够适应它,如果它有效,您就可以轻松完成

    groupedIngredients: Ember.computed.groupBy('groupTag')
    

    【讨论】:

    • 完美!非常感谢!在 ember 中要学习的东西太多了……这让迷雾稍微消散了一点。
    【解决方案2】:

    我的代码有类似的问题,它通常处理为计算属性设置错误的依赖项。

    根据您的代码,我会说您的 groupedIngredients: 属性可能类似于:

    .property('@each.groupTag')
    

    一旦设置正确,您应该能够从控制器中删除承诺,因为一旦承诺履行,它应该会自动更新。

    【讨论】:

    • 感谢您的提示也是解决方案的正确方向!
    猜你喜欢
    • 1970-01-01
    • 2013-06-29
    • 2014-02-25
    • 2017-12-18
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多