3

我有一个 EmailsController (ArrayController),它存储所有的电子邮件。我有一个 EmailController (ObjectController),它有一个参数,用于存储是否选择了实际的电子邮件。我正在尝试在电子邮件模板中实现一个按钮,用于选择或取消选择所有电子邮件。所以不知何故,我需要通过 EmailsController 的操作通知 EmailController 并更改 EmailController 的 isChecked 参数。

我正在尝试使用 itemController、需求和 controllerBinding 参数,但没有任何效果。

以下是控制器:

App.EmailsController = Ember.ArrayController.extend({
    needs: ["Email"],
    itemController: 'Email',
    checkAll: true,
    actions: {
        checkAllEmails: function() {
            this.toggleProperty("checkAll");
            console.log(this.get("checkAll"));
        } 
    }
});


App.EmailController = Ember.ObjectController.extend({
    needs: ["Emails"],
    controllerBinding: 'controllers.Emails',
    isChecked: true,
    checkAllChanged: function() {
        //this should execute, but currently it does not
        this.set("isChecked",this.get('controller.checkAll'));
    }.property("controller")
});

这是相应的 jsFiddle: http: //jsfiddle.net/JqZK2/4/ 目标是通过 Check All 按钮切换复选框的选择。

谢谢!

4

2 回答 2

4

您混合了几种不同的机制,并且使用了一些错误的约定。不过,找到这些东西并不总是那么容易,所以不要担心。

引用控制器

即使控制器是使用大写格式创建的,它们也以小写格式存储,您的needs属性应该是:

needs: ['emails'],

然后,您可以通过该controllers属性访问其他控制器:

this.get('controllers.emails.checkAll')

计算属性

计算属性可以用作变量的 getter/setter,也可以用作其他属性的别名。例如,如果您希望将isCheckedEmail 控制器上的属性直接链接到checkAllEmails 控制器的属性值,您可以这样做:

isChecked: function() {
  return this.get('controllers.emails.checkAll');
}.property('controllers.emails.checkAll')

尽管计算属性可以做更多的事情,但这种基本形式实际上只是一个计算别名,并且有一个实用函数可以使它更容易:

isChecked: Ember.computed.alias('controllers.emails.checkAll')

可观察的

observable 基本上创建了一个方法,当它观察到的值发生变化时将调用该方法。计算的别名会导致所有项目在您单击其中任何一个时取消选中或选中,因为它们的isChecked属性直接链接到checkAll父控制器的属性。而不是您的checkAllChanged方法标识为属性,它应该使用observes

checkAllChanged: function() {
  this.set("isChecked",this.get('controllers.emails.checkAll'));
}.observes("controllers.emails.checkAll")

这样,当checkAll父控制器上的属性更改时,此方法会将isChecked所有项目的属性更新为其值,但如果您取消选中或选中单个项目,它不会影响其他项目。

绑定

绑定有些被弃用;通过阅读 Ember github 存储库上的问题,我相信 Ember 的创建者似乎更喜欢使用计算属性、别名和 observables。这并不是说它们不起作用,如果您的目标是避免controllers.emails每次都必须输入,您可以像以前那样创建一个(不过我不会称它为控制器,因为这真的很模棱两可):

emailsBinding: 'controllers.emails'

改用计算别名:

emails: Ember.computed.alias('controllers.emails')

然后,您可以将观察者更改为:

checkAllChanged: function() {
  this.set("isChecked",this.get('emails.checkAll'));
}.observes("emails.checkAll")

这是您的 jsFiddle 的更新版本:http: //jsfiddle.net/tMuQn/

于 2014-04-18T04:58:41.513 回答
3

您可以遍历电子邮件,从父控制器更改它们的属性。您无需指定needs或观察变量。

App.EmailsController = Ember.ArrayController.extend({
    itemController: 'email',
    actions: {
      checkAllEmails: function() {
        this.forEach(function(email) {
          email.toggleProperty("isChecked");
        });
      } 
    }
});

此外,您通常不会像使用isChecked = true;那样设置初始值。我相信这是在原型上创建一个静态共享属性(不是你想要的)。相反,在 init 上设置属性,或者从您的原始 json 数据中传递它。

见代码:http: //jsfiddle.net/JqZK2/5/

于 2014-04-18T05:06:46.333 回答