window.App = new (Backbone.View.extend({
el: $("#app"),
Collections: {},
Models: {},
Views: {},
Routers: {},
events: {
'click button' : function(e) {
alert("Thank god!");
}
},
render: function(){
//for test purposes
console.log($("#app").find("button"));
console.log(this.$el.find('button'));
},
start: function(){
this.render();
new App.Routers.PostsRouter();
Backbone.history.start({pushState: true});
}
}))();
$(document).ready(function() { App.start() });
HTML看起来像这样
<body>
<div id="app">
<div id="posts"></div>
<button>Click me</button>
</div>
</body>
真正奇怪的是在render函数中从console.log输出。两个选择器是相同的,即使上下文相同,那么问题在哪里?
console.log($("#app").find("button")); //this returns correct button
console.log(this.$el.find('button')); //this returns 0 occurences (WTF?)
修改:
在el: "#app"
稍微改变后,仍然存在同样的问题。问题是(感谢@nemesv)在加载DOM之前实例化这个类。但是,在加载DOM之后不可能实例化,因为那时不可能使用该命名空间结构(例如,App.Model.Post = Backbone.Model.extend())。但是这个“命名空间结构的主视图”在codeschool.com课程中被引入作为某种良好实践。解决方案可以在http://jsfiddle.net/BckAe
答案 0 :(得分:3)
您已将el
指定为jquery选择器,但由于您位于对象文字内,因此在加载DOM之前会立即进行评估。
因此el: $("#app"),
不会选择任何内容。
您可以使用一个主干功能解决此问题,您可以将el
初始化为包含选择器的字符串。
因此,请将您的el
声明更改为:
el: "#app"
您的点击事件未被触发,因为您在加载DOM之前实例化您的视图,因此骨干无法对您进行事件委派。
因此,您需要将视图声明和创建分为两个步骤。并且只在加载DOM时实例化您的视图:
var AppView = Backbone.View.extend({
el: "#app",
//...
});
$(document).ready(function()
{
window.App = new AppView();
App.start()
});
演示:JSFiddle。