【问题标题】:How to iterate over class variables from Handlebars in ember-cli?如何在 ember-cli 中迭代 Handlebars 中的类变量?
【发布时间】:2015-01-10 06:59:13
【问题描述】:

我想在 ember-cli 中遍历 Handlebars 中的类变量数组以生成复选框(类别)列表,并根据模型所属的类别选中相应的复选框。

我有几个问题: - 我不知道如何在 ember-cli 中访问类变量。我已经看到在 ember.js 中显示的教程,它只是 App.Listing.CATEGORIES,但我的每个循环都没有通过。 - 如何勾选相应的方框?我下面有一些乱码,可能不起作用。

listing.js:

import DS from "ember-data";

var Listing = DS.Model.extend({
    categories: DS.attr(), // string array
});

Listing.reopenClass({
    CATEGORIES: ['park', 'outdoors']
});

export default Listing;

show.hbs:

<ul>
{{#each category in CATEGORIES}}
<li>{{input type="checkbox" name=category checked=categories.contains(category)}} {{category}}</li>

{{/each}}
</ul>

【问题讨论】:

    标签: ember.js ember-data ember-cli


    【解决方案1】:

    Handlebars 模板不能像那样查找类,像 categories.contains(category) 这样的复杂逻辑也不起作用。您需要向控制器或组件添加计算属性,以向模板提供代理对象。假设它是一个控制器,这里是一个粗略的例子:

    export default Ember.Controller.extend({
      selectableCategories: function() {
        var model = this.get('model');
    
        return model.constructor.CATEGORIES.map(function(category) {
          var categoryProxy = Ember.Object.create({
            model: model,
            name: category,
            checked: function(key, value) {
              var model = this.get('model');
    
              // setter; the checkbox value has changed
              if (arguments.length > 1) {
                if (model.get('categories').contains(this.get('name'))) {
                  model.get('categories').removeObject(this.get('name'));
                }
                else {
                  model.get('categories').addObject(this.get('name'));
                }
              }
    
              // getter; the template is checking whether the checkbox should be checked
              return model.get('categories').contains(this.get('name'));
            }.property('model.categories')
          });
    
          return categoryProxy;
        });
      }.property('model.categories')
    });
    

    selectableCategories 计算属性返回一个对象数组,这些对象观察模型的 categories 属性并表示是否在其中找到每个类别。

    然后在您的模板中,您可以像这样使用代理对象:

    {{#each category in selectableCategories}}
      {{input type="checkbox" name=category.name checked=category.checked}} {{category.name}}
    {{/each}}
    

    【讨论】:

    • 我把你上面的代码放到了 controllers/listings/show.js 中。 Chrome 调试器告诉我 model.constructor.CATEGORIES 是未定义的。为什么使用 model.constructor.CATEGORIES 而不是 model.CATEGORIES?无论如何,都没有工作。当我用硬编码数组替换时,错误消失了(不足为奇),并且我得到了正确数量的复选框,但没有类别名称。 Ember 调试器告诉我 selectableCategories 中有三个对象,但它们没有任何属性。我跟着你在做什么,所以不知道为什么它不起作用。
    • 嗯,抱歉没用。我认为您需要model.constructor.CATEGORIES,因为它存储在类中,而不是每个实例中。您可以向检查员核实是否属实。也许设置一个 JSBin 并且我可以进一步查看它?我写的答案没有与任何实时代码绑定,所以我可能错过了一些东西。
    • 您可以在返回model.constructor.CATEGORIES 的控制器上设置一个计算属性来验证该功能。此外,还有this library 用于此目的。
    • 我在模型字典定义中发现了一个缺少的逗号。修复使 model.constructor.CATEGORIES 参考工作。我设法在 JSBin 中复制了我剩下的问题(没有显示类别名称):jsbin.com/hidaqovigo/3/edit 你提到的插件看起来很棒。我对学习 Ember 很感兴趣,所以我可能会使用该插件,但想了解为什么当前代码不起作用。
    • 呃,我在构造代理对象时犯了一个简单的错误;应该使用Ember.Object.create 而不是new Ember.Object
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2015-02-12
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    相关资源
    最近更新 更多