我有一个Backbone View,用于表示特定元素将继承的一般元素。我有需要应用于所有元素的事件处理逻辑,以及特定于子类型元素的事件处理逻辑。我遇到了麻烦,因为子View有一个也由父View处理的事件的回调,因此当我尝试在两者中使用事件哈希时,永远不会调用子回调或父回调。让我用一些代码来说明:
var ElementView = Backbone.View.extend({
events: {
"mouseup": "upHandler",
"mousedown": "downHandler",
"mousemove": "moveHandler"
},
initialize: function() {
// add events from child
if (this.events)
this.events = _.defaults(this.events, ElementView.prototype.events);
this.delegateEvents(this.events);
}
});
var StrokeView = ElementView.extend({
events: {
"mousemove": "strokeMoveHandler"
}
});
我如何以可扩展的方式解决这个问题,特别是如果我以后会有另一个级别的继承?
答案 0 :(得分:8)
处理此问题的一种方法是对事件使用“名称空间”:
var ElementView = Backbone.View.extend({
events: {
"mouseup.element": "upHandler",
"mousedown.element": "downHandler",
"mousemove.element": "moveHandler"
},
initialize: function() {
// add events from child
if (this.events)
this.events = _.defaults(this.events, ElementView.prototype.events);
this.delegateEvents(this.events);
}
});
var StrokeView = ElementView.extend({
events: {
"mousemove.strokeview": "strokeMoveHandler"
}
});
事实上,这种方法是suggested in Backbone.js documentation。
答案 1 :(得分:4)
我已经做了类似的事情,利用了Backbone.js documentation中提到的JavaScript的虚假super
和初始化函数
var ElementView = Backbone.View.extend({
events: {
"mouseup": "upHandler",
"mousedown": "downHandler",
"mousemove": "moveHandler"
},
initialize: function() {
this.delegateEvents();
}
});
var StrokeView = ElementView.extend({
initialize: function() {
this.events = _.extend({}, this.events, {
"mousemove": "strokeMoveHandler"
});
// Call the parent's initialization function
ElementView.prototype.initialize.call(this);
}
});
var SubStrokeView = StrokeView.extend({
initialize: function() {
this.events = _.extend({}, this.events, {
"click": "subStrokeClickHandler",
"mouseup": "subStrokeMouseupHandler"
});
// Call the parent's initialization function
StrokeView.prototype.initialize.call(this);
}
});
var c = new SubStrokeView();
console.log(c.events);
// Should be something like
// click: "subStrokeClickHandler"
// mousedown: "downHandler"
// mousemove: "strokeMoveHandler"
// mouseup: "subStrokeMouseupHandler"
通过在initialize
函数中设置事件来实现神奇。如果您的原型中有多个events
属性,那么由于原型设计的工作原理,JavaScript只能看到最近的属性。
相反,通过这种方式,每个视图都设置自己的this.events
,然后调用其父级initialize
函数,后者又将this.events
与其事件一起扩展,依此类推。 / p>
您需要以这种特定方式设置this.events
:
this.events = _.extend({}, this.events, ...new events...);
而不是
_.extend(this.events, ...new events...);
以第二种方式执行此操作将使父事件(ElementView
)原型中的事件对象变得清晰。第一种方法确保每个模型都有自己的副本。