我已经开始使用backbone.js 并且遇到了一个问题。我希望能够通过 onclick 事件显示/隐藏 div(由视图呈现)。问题是事件仅适用于子元素,并且被单击的元素是视图的兄弟/父级。我已经通过在视图“初始化”函数中添加一个处理程序来解决这个问题,但我不认为这是要走的路。我也没有使用“主视图”,否则我怎样才能完成这项工作?
1 回答
如果没有父视图,那么您可以像这样在每个视图之外的视图之间连接事件。
var viewClicked = new ViewClicked();
var viewListening = new ViewListening();
viewListening.listenTo(viewClicked, "clicked:view", viewListening.respondToClick);
您不需要父视图来执行上述操作,即使正如评论所建议的那样,父视图可能是一个好主意。事实上,无论您是否在父视图中连接事件,该方法都是相同的!
因此,您可以通过在初始化函数中处理事件来按照自己的方式进行操作,但这会将一个视图耦合到另一个视图。或者,您可以像上面演示的那样进行操作,这可以防止视图耦合,但需要父视图、某种关闭或污染全局范围。通常最好不要将视图紧密耦合,因为它会减少封装和可能的重用,因此您可以考虑以某种方式采用上述方法。
最后,您可以使用某种中央事件总线(pub sub object),这在这个问题中进行了讨论。这将引入另一个对象,但允许您在视图的初始化函数中处理事件,但耦合不那么紧密(您将耦合到全局或范围事件总线,而不是特定视图)。
当然,您也可以在父视图中使用本地范围的事件总线 :)
更新
如果你只有一个视图并且锚点在视图之外,你可以在锚点上使用标准的 jQuery click 事件来调用视图上的切换函数。重要的是要注意_.bindAll
确保切换事件的上下文是视图对象。例如:
HTML
<a href="#" id="showView">click me</a>
<div id="myView"></div>
JAVASCRIPT
var MyView = Backbone.View.extend({
initialize: function() {
// _.bindAll binds functions called by events to the
// view (by passing it the view context as 'this'
_.bindAll(this, "toggle");
// put some content in the view
this.$el.append("Now you see me!");
},
toggle: function() {
// jQuery toggle function
this.$el.toggle();
}
});
var myView = new MyView({ el: $("#myView")});
$("#showView").click(myView.toggle);
我为您提供了一个工作小提琴,以便您可以看到它的实际效果。
我提到的关于使用父视图或某种闭包的初始点仍然是一个好主意。真的有理由不这样做吗?
更新 2
使用包含子视图的父视图执行此操作如下:
HTML
<div id="parentView"></div>
JAVASCRIPT
var ShowView = Backbone.View.extend({
events: {
"click #showView": "click"
},
click: function() {
this.trigger("showView:click");
},
render: function() {
this.$el.append('<a href="#" id="showView">click me</a>');
return this;
}
});
var MyView = Backbone.View.extend({
initialize: function() {
// _.bindAll binds functions called by events to the
// view (by passing it the view context as 'this'
_.bindAll(this, "toggle");
// put some content in the view
},
render: function() {
this.$el.append('Now you see me!');
return this;
},
toggle: function() {
// jQuery toggle function
this.$el.toggle();
}
});
var ParentView = Backbone.View.extend({
initialize: function() {
this.showView = new ShowView({
id: "showView"
});
this.myView = new MyView({
id: "myView"
});
this.listenTo(this.showView, "showView:click", this.myView.toggle)
},
render: function() {
this.$el.append(this.showView.render().$el);
this.$el.append(this.myView.render().$el);
return this;
}
});
var parentView = new ParentView ({el: $("#parentView") });
parentView.render();
这是一个演示它的工作小提琴。您可能认为对于您的问题的上下文而言,使用父视图的方法过于矫枉过正,您可能是对的!然而,随着您的应用程序变得越来越复杂,许多视图嵌套在许多级别上,您会发现父视图方法开始变得更有意义并开始发挥作用。