Backbone 重新加载模板时绑定事件

Backbone bind event when reload template

刚开始学习Backbone,下划线模板,不知道结构适不适合

问题是,当我重新加载模板时,如何从 Backbone 重新绑定事件,这是重新 运行 事件函数。

该示例只是加载一个索引页面,将 main_option 模板插入页面,并在 main_option 和 role_view 模板之间跳转。

这是我把路由器放在那里的app.js:

define(['jquery', 'underscore', 'backbone', 'views/role_view', 'views/main_options'], function ($, _, Backbone, rolePage, mainOptions) {

var appRouter = Backbone.Router.extend({

    $el: $('.container'),

    initialize: function () {
        this.mainOptionPage = mainOptions;
        this.loginView = rolePage;

    },

    routes: {
        "": "mainOption",
        "views/role_view": "login"
    },

    mainOption: function () {

        this.$el.html(this.mainOptionPage.render().$el);
    },

    login: function () {
        this.$el.html(this.loginView.render().$el);

    }
});

var router = new appRouter();
Backbone.history.start();

});

这是main_option.js

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){

var Person = Backbone.Model.extend({
    defaults: {
        name: 'Guest Worker',
        age: 23,
        occupation: 'worker'
    }
});

var testView = Backbone.View.extend({
    $el: $('#indexPage'),

    initialize: function () {
        var self = this;
        $.get('/test/templates/mainOptions.html').success(function (data) {
            self.template_loaded(data);
            template = _.template(data, {name: "Test"});
        }, 'html');

    },
    events: {
        'click .signButton': 'pageToSign'
    },



    pageToSign: function (e) {
        e.preventDefault();

        Backbone.history.navigate("views/role_view", {trigger: true});
    },

    template_loaded: function (html) {
        var template = _.template(html, {name: "Test"});

        this.$el.html(template);
        return this;
    }
});
var person = new Person;

return new testView({model: person});
});

最后一页是 role_view.js

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){

var role = Backbone.View.extend({


    initialize: function(){
        var self = this;

        $.get('/test/templates/chooseRole.html').success(function(html){
            self.template_loaded(html);
        });
    },

    events: {
        'click .parentButton': 'parentClick'
    },

    template_loaded: function(html) {
        var template = _.template(html, {name: "Test"});

        this.$el.html(template);
        return this;
    },

    parentClick: function(e) {
        e.preventDefault();
        Backbone.history.navigate("", {trigger: true});
    }


});

return new role();
});

谢谢。

你真正的问题是你在重用视图而不是根据需要销毁和创建它们。在你的路由器中,你有这个:

mainOption: function () {
    this.$el.html(this.mainOptionPage.render().$el);
},
login: function () {
    this.$el.html(this.loginView.render().$el);
}

你第一次调用this.$el.html,view就上去了,好像一切正​​常。然后你通过调用 this.$el.html 切换视图,一切似乎都还好。但是下次您切换视图时,您的事件就消失了。这是因为 jQuery 的 html 函数的工作方式;来自 fine manual:

When .html() is used to set an element's content, any content that was in that element is completely replaced by the new content. Additionally, jQuery removes other constructs such as data and event handlers from child elements before replacing those elements with the new content.

强调我的。调用this.$el.html会破坏之前内容的事件绑定(如this.mainOptionsPage.elthis.loginView.el)。

如果您根据需要创建和销毁视图:

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
    // Your Person model goes in its own file or possibly in the router file for now...
    var TestView = Backbone.View.extend({
        //...
    });
    return TestView; // Return the view "class", not an instance.
});

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
    var Role = Backbone.View.extend({
        //...
    });
    return Role;
});

define(['jquery', 'underscore', 'backbone', 'views/role_view', 'views/main_options', 'models/person'], function ($, _, Backbone, Role, TestView, Person) {
    var person = new Person; // The person model is managed here.
    var appRouter = Backbone.Router.extend({
        //...
        initialize: function () {
            // Don't need anything in here anymore.
        },
        //...
        mainOption: function () {
            // Create a new view when we need it.
            this.switchTo(new TestView({ model: person }));
        },
        login: function() {
            // Create a new view when we need it.
            this.switchTo(new Role);
        },
        switchTo: function(view) {
            // Destroy the old view since we don't need it anymore.
            if(this.currentView)
                this.currentView.remove();

            // Keep track of the new current view so that we can
            // kill it alter and avoid leaks.
            this.currentView = view;

            this.$el.html(this.currentView.render().el);
        }
    });
    //...
});