Javascript 如何在主干子视图中绑定单击事件
我在理解主干子视图中的事件绑定时遇到问题。我的观点定义如下:Javascript 如何在主干子视图中绑定单击事件,javascript,events,backbone.js,Javascript,Events,Backbone.js,我在理解主干子视图中的事件绑定时遇到问题。我的观点定义如下: TenantView = Backbone.View.extend({ events: { "click": "setActive" }, initialize: function() { this.parentEl = this.options.parentEl; return this.render(); }, template: new EJS({ url: '/scripts
TenantView = Backbone.View.extend({
events: {
"click": "setActive"
},
initialize: function() {
this.parentEl = this.options.parentEl;
return this.render();
},
template: new EJS({
url: '/scripts/templates/tenant.ejs'
}),
render: function() {
$(this.parentEl).children('ul').append(this.template.render(this.model));
return this;
},
setActive: function(event) {
return this.model.set('active', true);
}
});
模板只是由一个包含一个a
的li
组成。这样做,我的视图上的点击事件不会被捕获,我的方法setActive
永远不会被触发
当我通过el
属性(如el:'li'
扩展视图时,我的(2)个视图中的一个会正常工作并触发setActive
功能。第二种观点根本没有反应。如果在视图初始化期间插入el
属性,则工作视图的el
属性指向右侧的li
,失败的视图el
指向可在页面中找到的第一个li
正如大家所看到的,当谈到el
属性的含义时,我完全不知所措
问题是,如何将点击视图绑定到这个视图setActive
函数
谁能给我点化一下吗
问候
Felix通过引入您的
parentEl
属性并绕过视图元素的创建,您具有某种禁用的backbones自然行为。您基本上从未将视图的elz属性连接到任何东西
如果我没有弄错代码,TenantView
是租户列表中的单个列表项
在您的租户视图中
可以这样做以利用主干内置事件:
render: function() {
this.setElement(this.template.render(this.model));
$(this.parentEl).children('ul').append(this.$el);
return this;
}
setElement
函数将使用template
函数的返回值连接视图元素,并为您设置事件。在文档中,建议使用setElement
,只为el
属性赋值。还有一个漂亮的$el
属性,它将包含视图元素的缓存jQuery(或Zepto)对象
对个人来说,我会考虑这样的事情:
var TenantView = Backbone.View.extend({
// =========
// = Setup =
// =========
events: {
"click": "setActive"
},
template: new EJS({
url: '/scripts/templates/tenant.ejs'
}),
// =============
// = Lifecycle =
// =============
initialize: function(model, options) {
this.render();
},
render: function() {
var content = this.template.render(this.model);
this.$el.html(content);
return this;
},
// ==========
// = Events =
// ==========
setActive: function(event) {
return this.model.set('active', true);
}
});
var TenantList = Backbone.View.extend({
// =========
// = Setup =
// =========
id: "tenantList",
tagName: "ul",
// =============
// = Lifecycle =
// =============
initialize: function() {
this.render();
},
render: function() {
if (this.collection.length > 0) {
this.renderChildren();
}
},
renderChildren: function() {
var that = this;
this.collection.each(function(tenant) {
that.$el.append(new TenantView(tenant).$el);
});
}
});
首先,你可以阅读和阅读。这里给出了关于el
的解释
由于TenantView
具有parentEl
属性,我假设它是从某个parent\u视图中呈现的。我会建议一些类似下面的方法,并尝试一下
var ChildView = Backbone.View.extend({
tagName : "li", // change it according to your needs
events : {
"click": "setActive"
},
initialize : function() {
_.bindAll(this, "setActive");
// code to initialize child_view
},
render : function() {
// as I'm not familiar with the way you are using template,
// I've put simple call to render template, but it should render the
// content to be kept inside "li" tag
this.$el.html(this.template());
return this;
},
setActive : function(event) {
// code to be executed in event callback
}
});
var ParentView = Backbone.View.extend({
el : "#parent_view_el",
initialize : function() {
// parent view initialization code
},
render : function() {
// a place from where ChildView is initialized
// might be a loop through collection to initialize more than one child views
// passing individual model to the view
var child_view = new ChildView();
this.$("ul").append(child_view.render().$el); // equivalent to this.$el.find("ul")
return this;
}
});
希望能有帮助 旋风,谢谢你的回答。事实上,这几乎就是我正在做的。parentEl属性指向CollectionViews el属性(这是一个ul),因此我可以在ul中呈现我的ChildView。在父集合视图中,我迭代集合模型,并为每个模型创建一个ChildView实例。我觉得,这种方法是完全错误的。嗯,这就是我一直遵循的,对我来说非常有效:)阅读实际上解决了我的问题。见下面我的评论。再次感谢您的意见。托尔斯滕,谢谢您的回复。setElement似乎在渲染期间正确设置了“我的视图”的el属性。不幸的是,这两种方式都无法捕获单击事件。我认为我在CollectionView中呈现ChildView的整个方法是完全错误的。。。主干类希望您在初始化后拥有一个元素,并且仅使用render函数填充该元素。理论上,setElement
函数应该处理事件。你使用哪个版本的主干网?我使用的是0.9.2。到目前为止,解决这个问题的方法是将ChildView的标记名设置为'li'。然后从模板中删除li。我将我的ChildView的呈现方法更改为:this.el.innerHTML=this.template.render(this.model),并将我的CollectionView的呈现方法更改为:$(this.el).children('ul').append(viewInstance.render().el),其中viewInstance被迭代。我仍然不确定这种方法是否正确。