从另一个控制器访问控制器计算属性

时间:2014-09-07 17:47:53

标签: ember.js

我有以下控制器:

App.StudentIndexController = Ember.ObjectController.extend({
    hasDebt: function(){
        var totalCredit = this.get('totalCredit');
        var totalCreditSpent = this.get('totalCreditSpent');

        if (totalCreditSpent > totalCredit) 
        {
            return true;
        }
        else
        {
            return false;
        }
    }.property('payments.@each', 'lessons.@each'),

    availableCredit: function(){

        var totalCredit = this.get('totalCredit');
        var totalCreditSpent = this.get('totalCreditSpent');

        return totalCredit - totalCreditSpent;
    }.property('payments.@each', 'lessons.@each'),

    totalCredit: function(){
        var totalCredit = 0;

        var payments = this.get('payments');
        payments.forEach(function(payment){
            totalCredit += payment.get('amount');
        });

        return totalCredit;
    }.property('payments.@each', 'lessons.@each'),

    totalCreditSpent: function(){
        var totalCreditSpent = 0;
        var lessons = this.get('lessons');
        lessons.forEach(function(lesson){
            var duration = lesson.get('duration');
            var price;
            switch (duration)
            {
                case 45: price = 15; break;
                case 60: price = 20; break;
            }
            totalCreditSpent += price;
        });

        return totalCreditSpent;
    }.property('payments.@each', 'lessons.@each')
});

我需要在以下控制器中访问其中一些计算属性,以便能够根据每个学生的债务计算totalDebt:

App.StudentsIndexController = Ember.ArrayController.extend({
    totalDebt: function(){
        var students = this.model.content;
        var totalDebt = 0;

        students.forEach(function(student){
            if (student.hasDebt)
            {
                totalDebt += student.availableCredit;
            }
        });

        return totalDebt;
    }.property('student.payments.@each', 'student.lessons.@each'),
});

然而,这不起作用。我想它并不是因为计算属性在控制器中,我试图从模型中访问它们。

StudentIndexController控制器StudentsIndexController访问计算属性的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:4)

控制器可以通过needs属性相互访问(参见this entry in the EmberJS guide

needs属性是一个控制器名称数组,然后您可以通过controllers属性访问控制器,如下所示。

var StudentsIndexController = Ember.Controller.extend({
  needs: ['studentIndex'],
  totalDebt: Ember.computed('controllers.studentIndex.payments.@each', ....),
  ....
});

如果这对您来说有点冗长,您可以随时为控制器添加别名。

var StudentsIndexController = Ember.Controller.extend({
 needs: ['studentIndex'],
 student: Ember.computed.alias('controllers.studentIndex'),
 totalDebt: Ember.computed('student.payments.@each', ....),
 ....
});

最后,如果您更喜欢语法,还可以将needs值更改为单个字符串,例如needs: 'studentIndex'

答案 1 :(得分:0)

由于你想要访问每个模型的计算属性,而不仅仅是一个,所以看起来你的需求会超出needs api。使用needs功能可以访问该名称的 singleton 控制器。如果您可以访问一个StudentIndexController实例,则无法确定哪个模型(如果有)存在于该控制器中。您需要使用itemController api将每个学生用学生控制器的非单例实例包装。

请参阅此jsbin解决您的问题(使用简化的模型)。 http://emberjs.jsbin.com/gexuj/2/edit

要点是:您的数组控制器将itemController属性定义为您希望在上下文中包装每个模型的控制器的常规名称。然后,您可以访问每个学生的那些很酷的计算属性,并根据需要进行聚合。

App.StudentsIndexController = Ember.ArrayController.extend({
  itemController: 'studentIndex',
  doesAnybodyHaveDebt: function () {
    return !!this.filterBy('hasDebt').length;
  }.property('@each.hasDebt')
});

在此处查找有关项目控制器属性的更多信息:http://emberjs.com/api/classes/Ember.ArrayController.html