用于从动作设置控制器计算属性的Ember方法

时间:2016-01-26 02:45:44

标签: ember.js ember-data

我是Ember的新手,并尝试遵循Data Down Action Up方法,我的控制器充当主要的“组件”,其中许多组件向控制器发送动作以设置最终会涓流的模型的值向组件返回新值。我知道控制器正在消失,但如果你愿意,我需要这个控制器来保持所有的状态......

我正在努力学习我的方法,因为我想在我的控制器上设置一些监视模型属性的计算属性。最困难的似乎是设置其中一个计算属性的值,这些属性需要在操作触发时设置其他属性。这是我的一些控制器(参见下面的更新示例,这留待参考):

//controllers/groupPlanning.js

import Ember from 'ember';

export default Ember.Controller.extend({

    groups: Ember.computed('model.@each.groups', function(){
        return this.get('model').get('groups');
    }),

    enrollmentGroup: Ember.computed('groups', function(){
        this.get('groups').forEach(function(group) {
            if (group.get('name') === 'Enrollment'){
                return group;
            }
        }):

    }),

    enrollmentGroupPercent: Ember.computed('enrollmentGroup', function() {
        var group = this.get('enrollmentGroup');
        return group.get('year') * this.get('someOtherNumber');
    }),

   ...

    actions: {
        setGroupYear: function(year){
            var group = this.get('enrollmentGroup');
            group.set('year', year);
            group.save();
        }
    }

});

更新:上面的例子有一些数字缺陷,下面的代码是显示每个Lux解决方案的更正:

//controllers/groupPlanning.js

import Ember from 'ember';

export default Ember.Controller.extend({

    groups: Ember.computed('model.groups.[]', function(){
        return this.get('model.groups');
    }),

    enrollmentGroup: Ember.computed('groups', function(){
        return this.get('groups').findBy('name', 'Enrollment');
    }),

    enrollmentGroupPercent: Ember.computed('enrollmentGroup.year', 'someOtherNumber', function() {
        var group = this.get('enrollmentGroup');
        return group.year * this.get('someOtherNumber');
    }),

   ...

    actions: {
        setGroupYear: function(year){
            var group = this.get('enrollmentGroup');
            group.set('year', year);
            group.save();
        }
    }

});

除了询问这种方法是否合理之外,我在实际设置enrollmentGroup的价值时遇到了问题:

group.set('year', year);

抛出

的错误

Uncaught TypeError: Cannot read property 'set' of undefined

这里的任何指针都将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:1)

首先,您对enrollmentGroupPercent的依赖缺少year。而不是

enrollmentGroupPercent: Ember.computed('enrollmentGroup', function() {

使用

enrollmentGroupPercent: Ember.computed('enrollmentGroup.year', 'someOtherNumber', function() {

你肯定需要year因为你修改了它。

第二,你的问题:

  

未捕获的TypeError:无法读取未定义的属性'set'

此时group似乎null / undefined!也许用调试器检查一下!

所以肯定enrollmentGroup什么都不返回。也许你没有名为Enrollment的小组。但我想你可能会遇到更棘手的事情。

我认为您的modelember-data模型,groupshasMany关系。

这段代码没有任何意义:

groups: Ember.computed('model.@each.groups', function(){
    return this.get('model').get('groups');
}),

首先,我建议在将this.get('model').get('groups')设置为this.get('model.groups')后,将get(this, 'model.groups')替换为getEmber.get

然后在@each上使用model,这只有在model是数组时才有意义。

您可能希望在添加/删除组时重新计算CP。在这种情况下,使用model.groups.[]作为依赖关键字。如果要汇总来自组的数据,例如计算总数,您可以使用model.groups.@each.quantity,只要任何组中的数量发生变化,CP就会重新计算。

如果name可以更改,您实际上需要这样做,因为组列表不会仅更改名称,所以您可能稍后将名称设置为Enrollment

现在你应该可以替换

enrollmentGroup: Ember.computed('groups', function(){

enrollmentGroup: Ember.computed('groups.@each.name', function(){

但是由于当前版主版本中的Bug无效

重要的是要了解存储方法和模型关系不会返回正常值,而是返回ArrayProxyObjectProxyPromiseArrayPromiseObject的实例。< / p>

所以实际上groups是PromiseObjects的PromiseArray。但您可以在groups CP中打开PromiseObject:

groups: Ember.computed('model.groups.[]', function(){
    let promise = this.get('model.groups').then(groups => Ember.RSVP.all(groups));
    return DS.PromiseArray({promise});
}),

然后使用content观察实际值:

enrollmentGroup: Ember.computed('groups.content.@each.name', function(){
    return this.get('groups').findBy('name', 'Enrollment');
}),

现在enrollmentGroup应该始终是最新的!因此,您可能遇到的唯一问题是您早点开始行动!

如果您仍有问题,请在ember-twiddle上提供一个最小示例!

答案 1 :(得分:0)

您正在尝试设置计算机的值,它不会像这样工作。我会建议observer approach

enrollmentGroupObserver: Ember.observer('groups', function(){
        this.get('groups').forEach(function(group) {
            if (group.get('name') === 'Enrollment'){
                this.set('enrollmentGroup', group);
            }
        }):

    }),
enrollmentGroup: null,