Eugene
Eugene

Reputation: 1789

Backbone: Events not fire on next render

I have code like this. I click on button and it works only few time. Chrome says no events listener on button. But View creates button and View has click event . Can you help me?

//buttons view
var NavigateBar = Backbone.View.extend({    
    events : {
        'click button#back' : 'onBack',
        'click button#next' : 'onNext',
        'hover' : function() {console.log('hover on navigate')}
    },
    initialize: function(options) {
//buttons html
        this.backDiv = '<button id="back" class="btn btn-primary btn-large pull-left">Back</button>';
        this.nextDiv = '<button id="next" class="btn btn-primary btn-large pull-right">Next</button>';
//save options
        this.back = this.options.back;
        this.next = this.options.next;
    },
//buttons event
    onBack : function(e) {
        e.preventDefault();
        app.navigate(this.back, {trigger: true});
    },
    onNext : function(e) {
        e.preventDefault();
        app.navigate(this.next, {trigger: true});
    },
//render
    render: function() {
        this.$el.html("");
        this.$el.append(this.backDiv);
        this.$el.append(this.nextDiv);
        return this;
    }
    });

//create router class
    var AppRouter = Backbone.Router.extend({
    routes: {
        "" : 'home',
        ":id" : 'test'
    },
//create different views
   initialize:function () {        
        this.homeView = new NavigateBar({
//pass options to view
            back: "1",
            next: "2"
        });
        this.testView = new NavigateBar({
            back: "3",
            next: ""
        });
    },
//route actions
    home : function() {
        $('#view-goes-here').html(this.homeView.render().el);
    },
    test : function(e) {
        $('#view-goes-here').html(this.testView.render().el);
    }
});

//create app
$(function(){  
    app = new AppRouter();
    Backbone.history.start();
});
​

Demo: http://jsfiddle.net/3Jaru/3/, click twice on next button and you see

Upvotes: 0

Views: 350

Answers (1)

Vincent Briglia
Vincent Briglia

Reputation: 3068

You're keeping a reference to the view alive which is causing the trouble so that when jQuery tries to rebind the events it does not do so. As a general rule, I don't define a reference to a view in the initialize method ever, always outside of it so that I can make sure it gets overwritten when a parent method asks for a new instance of the view.

home: function () {
    view = new NavigateBar({
        back: "1",
        next: "2"
    });
    $('#view-goes-here').html(view.render().el);
    // and if you really want to be able to reference it
    this.homeView = view;
},
test: function (e) {
    view = new NavigateBar({
        back: "3",
        next: ""
    });
    $('#view-goes-here').html(view.render().el);
    // and if you really want to be able to reference it
    this.homeView = view;
}

a better approach would to always make sure that if there is a view defined, to destroy it so that

home: function () {
    /* create a method on the NavigateBar view to clear anything 
     * that needs clearing, such as model binds or funky events
     */
    this.homeView && this.homeview.destroy(); 
    view = new NavigateBar({
        back: "1",
        next: "2"
    });
    $('#view-goes-here').html(view.render().el);
    this.homeView = view;
},

Upvotes: 1

Related Questions