所以这是我在jsfiddle的应用程序示例:http://jsfiddle.net/GWXpn/1/
问题是点击事件根本没有被触发。我没有在控制台中收到任何JS错误。
首先,我希望显示一个无序列表,其中包含几个项目,每个项目都应该是可点击的。这就是我所做的:
var FooModel = Backbone.Model.extend({});
var ListView = Backbone.View.extend({
tagName: 'ul', // name of (orphan) root tag in this.el
initialize: function() {
_.bindAll(this, 'render'); // every function that uses 'this' as the current object should be in here
},
render: function() {
for (var i = 0; i < 5; i++) {
var view = new SingleView({
model: new FooModel()
});
$(this.el).append(view.render().el);
}
return this; // for chainable calls, like .render().el
}
});
var SingleView = Backbone.View.extend({
tagName: 'li', // name of (orphan) root tag in this.el
initialize: function() {
_.bindAll(this, 'render', 'click'); // every function that uses 'this' as the current object should be in here
},
events: {
"click": "click"
},
click: function(ev) {
console.log("aaa");
alert(333);
},
render: function() {
$(this.el).append("aaa");
return this; // for chainable calls, like .render().el
}
});
我想将我的应用分成多个模块(标题,正文,页脚),所以我创建了一个抽象模型并从中扩展了我的模块:
var AbstractModule = Backbone.Model.extend({
getContent: function () {
return "TODO";
},
render: function () {
return $('<div></div>').append(this.getContent());
}
});
var HeaderModule = AbstractModule.extend({
id: "header-module",
});
var BodyModule = AbstractModule.extend({
id: "body-module",
getContent: function () {
var listView = new ListView();
return $("<div/>").append($(listView.render().el).clone()).html();
}
});
var ModuleCollection = Backbone.Collection.extend({
model: AbstractModule,
});
然后我创建了我的主视图并渲染了所有子视图:
var AppView = Backbone.View.extend({
el: $('#hello'),
initialize: function (modules) {
this.moduleCollection = new ModuleCollection();
for (var i = 0; i < modules.length; i++) {
this.moduleCollection.add(new modules[i]);
}
},
render: function () {
var self = this;
_(this.moduleCollection.models).each(function (module) { // in case collection is not empty
$(self.el).append(module.render());
}, this);
}
});
var appView = new AppView([HeaderModule, BodyModule]);
appView.render();
任何想法为什么?
答案 0 :(得分:3)
你在一行中有两个错误:
return $("<div/>").append($(listView.render().el).clone()).html();
首先,除非您明确要求,否则clone
不会复制事件:
通常,绑定到原始元素的任何事件处理程序都不会复制到克隆。可选的
withDataAndEvents
参数允许我们更改此行为,而是复制所有事件处理程序,并绑定到元素的新副本。
[...]
从jQuery 1.5开始,withDataAndEvents
可以选择使用deepWithDataAndEvents
进行增强,以复制克隆元素的所有子项的事件和数据。
您正在克隆<ul>
,因此您需要将这两个标记设置为true
。
此外,html
会返回一个字符串,并且字符串没有事件,因此您可以将事件杀死事件加倍。
我不明白为什么你要克隆任何东西,你应该返回el
并完成它:
return listView.render().el;
如果你坚持克隆,那么你需要这样的东西:
return $(listView.render().el).clone(true, true);
但那只是毫无意义的忙碌工作。
BTW,'title'
和'Title'
是不同的模型属性,因此您需要说:
console.log(this.model.get("title") + " clicked");
而不是
console.log(this.model.get("Title") + " clicked");
另外,Backbone集合有很多Underscore methods mixed in所以不要直接搞乱集合的models
,你现在说的是:
_(this.moduleCollection.models).each(...)
只是说:
this.moduleCollection.each(...)
正如Loamhoof所提到的,0.3.3是古代历史,请升级到Backbone,Underscore和jQuery的新版本。您还应该阅读更改日志,以便使用较新的功能(例如this.$el
代替$(this.el)
,减少_.bindAll
次来电,listenTo
,...)。< / p>
部分更正的演示(包括更新的库):http://jsfiddle.net/ambiguous/e4Pba/
我也扯掉了alert
调用,这是一种可恶的调试技术,如果你遇到意外的无限循环会导致巨大的混乱,console.log
更友好。