我想将一个mixin添加到已经创建的Ember类中.(该类在库中定义,实际上是Ember本身;它是LinkView).
我看到我们可以做到mixin.apply(obj),但这会将mixin应用于类的实例.我想将mixin添加到类中,因此它会自动混合到所有新创建的对象中.
我试图覆盖init类的方法,使用reopenClass,并在mixin.apply(this)那里,将mixin应用于实例,然后调用原始init方法,但这似乎不起作用,因为mixin布线在init方法中设置,它是我到达时已经太晚了.
reopenClass似乎不接受像mix一样的mixin参数extend.它的代码似乎表明它正在使用mixins做一些事情,但无论它是什么它都不起作用:
a = Ember.Object.extend().reopenClass(Ember.Mixin.create({mixval: 1});
a.create().get('mixval'); // undefined
Run Code Online (Sandbox Code Playgroud)
我知道我可以创建自己的类MyLinkView = Ember.LinkView.extend(mixin, ...,但不幸的是原始的类名在库中显式引用,所以我真的更愿意弄清楚如何使用我的mixin扩展原始类.
我试验过Ember.LinkView = Ember.LinkView.extend(mixin, ....这似乎很危险,虽然它似乎有效.但是在这种特殊情况下,它对我没有帮助,因为Ember代码中的引用(在{{link-to}}帮助程序的定义中)是类的内部版本,而不是完全限定的Ember.LinkView.
有任何想法吗?
小智 5
解决方案很简单
Klass = Parent.extend({init: {...}});
Mixin = Ember.Mixin.create({init: {...}});
Klass.reopen(mixin);
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作,包括超级链.换句话说,呼叫Klass.create().init()将调用mixin init,并从那里调用super将调用原始Klass#init.
在研究这个问题的过程中,我发现了一些有趣的东西reopen.即使参数不是mixin,它也被视为一个(在内部,它实际上创建了一个临时的).这意味着,如果你这样做
Klass.reopen({
init: function() {
this._super.apply(this, arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
调用super实际上是调用原始类init,而不是init父类.换句话说,init在a reopen中指定不替换init类上的现有,它或多或少的层位于它之上.我无法在Ember文档中的任何位置看到此行为,但它在正确的情况下似乎有用.