在Backbonejs的主视图中单击事件未触发

时间:2013-02-12 09:09:11

标签: events button backbone.js click

我真的很奇怪。我正在尝试实现“root”视图,它也可以作为一些命名空间结构。在codeschool.com课程第二部分中介绍了相同的原则。在这个根视图中,我想捕获事件“单击按钮”,但这就是问题所在。当我点击按钮时没有发生任何事情。

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

找到

1 个答案:

答案 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