Ember:在创建后将mixin添加到类中

时间:2014-07-24 07:03:16

标签: ember.js mixins

我想将mixin添加到已经创建的Ember类中。 (该类在库中定义,实际上是Ember本身;它是LinkView)。

我发现我们可以mixin.apply(obj),但这会将mixin应用于该类的实例。我想将mixin添加到类中,因此它会自动混合到所有新创建的对象中。

我尝试使用init覆盖类的reopenClass方法,并在那里执行mixin.apply(this),将mixin应用于实例,然后调用原始{{1}方法,但这似乎不起作用,因为mixin布线是在init方法中设置的,而且到达它时已经太晚了。

init似乎不接受像reopenClass这样的mixin参数。它的代码似乎表明它正在使用mixins做一些事情,但无论它是什么都不起作用:

extend

我知道我可以使用a = Ember.Object.extend().reopenClass(Ember.Mixin.create({mixval: 1}); a.create().get('mixval'); // undefined 创建自己的类,但遗憾的是原始类名在库中显式引用,所以我真的更愿意弄清楚如何使用我的mixin扩展原始类。

我尝试了MyLinkView = Ember.LinkView.extend(mixin, ...。这似乎很危险,虽然它似乎有效。但在这种特殊情况下它并没有帮助我,因为Ember代码中的引用(在Ember.LinkView = Ember.LinkView.extend(mixin, ...帮助器的定义中)是类的内部版本,而不是完全限定的{{link-to}}

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

解决方案就是

Klass = Parent.extend({init: {...}});
Mixin = Ember.Mixin.create({init: {...}});
Klass.reopen(mixin);

一切都按预期工作,包括超级链。换句话说,拨打Klass.create().init()的电话会调用mixin的init,并且从那里拨打超级电话会调用原始的Klass#init

在研究这个问题的过程中,我发现了一些关于reopen的有趣内容。即使参数不是mixin,它也被视为一个(在内部,它实际上创建了一个临时的)。这意味着,如果你这样做

Klass.reopen({
  init: function() {
    this._super.apply(this, arguments);
  }
});

super的调用实际上是调用原始init,而不是父类中的init。换句话说,在init中指定reopen不会替换类上现有的init,它或多或少 layers 在它的上面。我无法在Ember文档中的任何位置看到此行为,但它在正确的情况下似乎有用。