我想将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}}
。
有什么想法吗?
答案 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文档中的任何位置看到此行为,但它在正确的情况下似乎有用。