Petr Brazdil
Petr Brazdil

Reputation: 241

Click event not firing in main view in Backbonejs

I have really weird problem. I am trying to implement "root" view which also works as some namespace structure. Same principle introduced in codeschool.com course part II. In this root view, I want to catch event "click button", but that's the problem. When I click on button nothing happened.

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() });

The HTML look like this

<body>
    <div id="app">
        <div id="posts"></div>

        <button>Click me</button>
    </div>
</body>

And what's really weird is output from console.log in render function. Both selectors are same, even the context is same, so where is problem?

console.log($("#app").find("button")); //this returns correct button
console.log(this.$el.find('button')); //this returns 0 occurences (WTF?)

EDIT: After little change at el: "#app", still same problem. Problem was (thanks to @nemesv) in instantiating this class before DOM is loaded. But however, it's not possible to instantiating after DOM is loaded, because then it's not possible to use that namespace structure (eg. App.Model.Post = Backbone.Model.extend() ). But this "main view with namespace structure" is introduced in codeschool.com course as some sort of good practice. Solution can be found there http://jsfiddle.net/BckAe

Upvotes: 2

Views: 171

Answers (1)

nemesv
nemesv

Reputation: 139758

You have specified your el as a jquery selector but because you are inside an object literal it evaluates immediately so before the DOM has been loaded.

So the el: $("#app"), won't select anything.

You can solve this by using one of the backbone features that you can initilaize the el as a string containing a selector.

So change your el declaration to:

el: "#app"

Your click event is not triggered because you instantiate your view before the DOM is loaded so backbone cannot do the event delegation your you.

So you need separate your view declaration and creation into two steps. And only instantiate your view when the DOM is loaded:

var AppView = Backbone.View.extend({
   el: "#app",  
   //...
});

$(document).ready(function() 
{ 
    window.App = new AppView();
    App.start() 
});

Demo: JSFiddle.

Upvotes: 3

Related Questions