【问题标题】:Ember Computed properties and Handlebars templatesEmber 计算属性和 Handlebars 模板
【发布时间】:2016-02-10 01:14:36
【问题描述】:

在我的 Ember 控制器中,我有 2 个计算属性 (CP),如下所示;

itemsWithData: function() {
    var dataItems = [];

    return dataItems;
}.property('containsFailure'),
someArray: function() {
    var items = this.get('itemsWithData');
    var someArray = [];

    return someArray;
}.property('itemsWithData')

现在在我的 Ember Handlerbars 模板中,虽然我只使用 someArray CP 来迭代和显示值,但我没有使用其他 CP(即 itemsWithData)

但是如果我没有在我的模板中引用 itemsWithData,那么在我的控制器中也不会执行同样的操作(所以即使 someArray 也不会执行,因为它依赖于 itemsWithData)

只有当我显式添加如下虚拟引用时才会执行;

{{#each itemsWithData as |data|}}
{{/each}}

这就是 CP 在控制器/模板中的工作方式吗?我需要一种方法,这样我就不必在我的模板中添加这个虚拟代码。

【问题讨论】:

    标签: javascript ember.js handlebars.js


    【解决方案1】:

    由于您正在观察一个数组,它应该是property('itemsWithData.[]')'[]' 观察数组中其对象集的任何更改(即添加和删除对象),但如果这些对象的属性发生更改,则不会触发。请参阅文档here

    如果你想观察数组中每个元素的特定属性,那就是property('itemsWithData.@each.name'),它观察itemsWithData中每个元素的名称集合。如果添加或删除元素,它也会触发。请参阅文档here

    属性是惰性计算的(而观察者不是),因此将itemsWithData 添加到您的模板会强制计算itemsWithData。如果它没有在其他任何地方调用,则不会被计算。

    还要注意 Ember overrides the native array。因此,如果您将Ember.EXTEND_PROTOTYPESEmber.EXTEND_PROTOTYPES.Array 设置为false,则观察数组可能不起作用。

    【讨论】:

    • 非常感谢...但是您能否通过一些示例来解释 .[] 和 .@each 以更清楚地了解用法..
    • 这样更有帮助吗?
    • 所以如果我理解正确...假设我有 itemsWithData: [ obj1: { prop1: '1', prop2: '2' }, obj2: {} ] 在这种情况下,如果我只是说property('itemsWithData'),即使obj1.prop1的值改变也会触发,但是如果我说property('itemsWithData.[]'),如果说obj1.prop1变成'2'就不会触发,但只有当 obj1 或 obj2 被删除或新的 obj3 被添加时才会触发。如果我的理解正确,请告诉我
    • property('itemsWithData') 不会触发,除非 itemsWithDatanull 更改为数组,反之亦然。 property('itemsWithData.[]') 将在您从数组中添加或删除项目时触发(如您所说),但如果项目的属性发生更改则不会触发。如果你想在每个对象上观察prop1,它是property('itemsWithData.@each.prop1)。如果您遇到问题,请注意在 Ember 2.x 中有一个与此相关的 bug