Backbone.js 在主干网中进行视图混合的正确方法
我一直在扩展基本主干视图,每个部分都有一个基本视图,这样我就可以在多个级别上进行扩展。我的问题是,进行视图混合最有效的方法是什么:可以混合到任何视图中的可重用视图部分。例如:Backbone.js 在主干网中进行视图混合的正确方法,backbone.js,Backbone.js,我一直在扩展基本主干视图,每个部分都有一个基本视图,这样我就可以在多个级别上进行扩展。我的问题是,进行视图混合最有效的方法是什么:可以混合到任何视图中的可重用视图部分。例如: var BaseProfile = Backbone.View.extend({ ...}); var UserProfile = BaseProfile.extend({ ...}); var VideoSupport = Backbone.View.extend({ ...}); 将VideoSupport视图(一个
var BaseProfile = Backbone.View.extend({ ...});
var UserProfile = BaseProfile.extend({ ...});
var VideoSupport = Backbone.View.extend({ ...});
将
VideoSupport
视图(一个事件对象和一些方法)与UserProfile
视图混合在一起的最佳方法是什么?underline.js库提供了一种满足您需要的扩展
方法。您可以在任何对象上定义功能,然后将所有方法和属性从该对象复制并粘贴到另一个对象
主干网在视图、模型和路由器上的extend
方法是下划线的extend
的包装器
var MyMixin = {
foo: "bar",
sayFoo: function(){alert(this.foo);}
}
var MyView = Backbone.View.extend({
// ...
});
_.extend(MyView.prototype, MyMixin);
myView = new MyView();
myView.sayFoo(); //=> "bar"
您可以使用这个要点我需要更接近ruby如何处理模块的覆盖和调用混合方法(ala super)的能力。如果mixin方法存在于类中,那么简单的扩展方法将对其进行重击。由于我在CoffeeScript中构建了所有内容,因此我可以访问super对象,该对象允许我填充方法。它还将自动合并事件对象,以便您可以在mixin中定义事件处理程序
_.extend Backbone,
mixin: (klass, mixin, merge) ->
debugger unless mixin
mixin = mixin.prototype || mixin
merge ||= ["events"]
sup = _.extend({},klass.__super__)
for name,func of mixin
if base = sup[name] && _.isFunction(base)
sup[name] = ->
func.apply this, arguments
base.apply this, arguments
else
sup[name] = func
hp = {}.hasOwnProperty
prototype = klass.prototype
for name,func of mixin
continue unless hp.call(mixin,name)
continue if _(merge).contains name
prototype[name] = func unless prototype[name]
klass.__super__ = sup
_(merge).each (name) ->
if mixin[name]
prototype[name] = _.extend({},mixin.events,prototype.events)
@
用法
我可能会建议使用它,它提供了一种非常简洁的方式来指定mixin(即继承):
我在这篇文章中详细介绍了它。您可以使用嵌入到原型链中的混音
var Editable = {
edit: function(){
console.log('edit');
}
};
var Article = Backbone.Model.mix(Editable).extend({
initialize: function(){
Backbone.Model.prototype.initialize.call(this);
this.edit(); // logs "edit"
}
});
另一个选项是提供AOP样式的混合功能(您可以在扩展对象方法的调用之前、之后或前后注入自定义行为)。感谢Derek,我认为默认值更合适,这样混合视图属性和方法就不会被覆盖。不过,正确的做法是,如果mixin将扩展它所混入的“类”的事件和init函数。另外,在您的示例中,您是否会扩展MyView.prototype而不是MyView函数类?这是一种方法,但需要注意的是,您通常希望扩展prototype。@maxl0rd-完全正确。我改变了它,以反映最常见的情况。在所有人中,德里克都知道这一点,但我认为我应该对最常见的情况给出答案是的,那应该在原型上。感谢您对有关使用u.defaults而不是u.extend.的评论进行编辑+1。。需要注意的是,人们可能不理解Derick在做什么,因为默认值是一个不太广为人知的功能。虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能会无效。@S.L.Barth-虽然我同意内联代码更有用-这是一个具有社区编辑功能的系统,因此请随意复制此处的代码以改进anser。在IE8中使用此方法时,我遇到了一些麻烦。Firefox、Chrome、Safari和IE9+目前正在运行。知道为什么它在IE8中不起作用吗?IE8中的控制台根本不显示任何消息…+1表示鸡尾酒。与接受的答案不同,此解决方案合并了mixin和View事件散列(以及任何其他对象,如木偶的ui或modeleevents散列)。
var Mixin = {
initialize: function() {
console.log("I'll be called as well as the class's constructor!");
}
};
var View = Backbone.View.extend({
mixins: [ MyMixin ]
});
var Editable = {
edit: function(){
console.log('edit');
}
};
var Article = Backbone.Model.mix(Editable).extend({
initialize: function(){
Backbone.Model.prototype.initialize.call(this);
this.edit(); // logs "edit"
}
});