主干不触发事件
Backbone Not Firing Events
这是我的应用在jsfiddle中的一个例子:http://jsfiddle.net/GWXpn/1/
问题是click事件根本没有被触发。我在控制台没有得到任何JS错误。
首先,我想显示一个无序列表,其中包含一对if项,每个项都应该是可点击的。我是这样做的:
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
}
});
我想把我的应用分成多个模块(header, body, footer),所以我创建了一个抽象模型,并从中扩展了我的模块:
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();
知道为什么吗?
一行有两个bug:
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);
但那只是毫无意义的忙碌工作。
顺便说一句,'title'
和'Title'
是不同的模型属性,所以你会想说:
console.log(this.model.get("title") + " clicked");
不是console.log(this.model.get("Title") + " clicked");
此外,主干集合有很多下划线方法混合在一起,所以不要直接与集合的models
混淆,你目前说:
_(this.moduleCollection.models).each(...)
说:
this.moduleCollection.each(...)
正如Loamhoof提到的,0.3.3已经过时了,请升级到主干、下划线和jQuery的新版本。您还应该阅读更改日志,以便您可以使用较新的功能(例如this.$el
代替$(this.el)
,减少_.bindAll
调用,listenTo
,…)。
部分修正的演示(包括更新的库):http://jsfiddle.net/ambiguous/e4Pba/
我还去掉了alert
调用,这是一个令人讨厌的调试技术,如果您进入意外的无限循环,可能会导致巨大的混乱,console.log
更友好。
- 分派点击事件并保留击键修饰符
- 模糊事件的Javascript测试
- keyup事件处理程序更改焦点不适用于快速键入
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 如何使Javascript动态html表及其上的事件
- 使用类从一个标记中双击事件
- 如何在未直接触发的情况下停止事件
- 如何在elfinder插件(一个文件管理器插件)上获得上传前事件
- 对iPad上的点击事件反应缓慢
- 事件和状态
- Fancybox是否将Click事件静音
- 主干-不管怎样,检查事件以前是否绑定过
- 从控制器返回后Ajax启动事件激发
- 如何从画布上的某个移动事件中获取X和Y
- Jquery:未触发select事件
- JsFiddle上的鼠标事件不起作用
- 只覆盖箭头键滚动事件
- $window.ga在AngularJS事件中未定义
- cron作业与Javascript计时事件
- ng更改事件不适用于Dropdown