重载模板时的骨干绑定事件

时间:2015-10-02 10:36:06

标签: javascript jquery templates backbone.js underscore.js

我刚刚开始使用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();
});

感谢。

1 个答案:

答案 0 :(得分:0)

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

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

你第一次打电话给this.$el.html,视图上升,一切似乎都没问题。然后通过调用this.$el.html切换视图,一切似乎都没问题。但是下次切换视图时,您的活动就消失了。这是因为jQuery的html函数的工作方式;来自fine manual

  

.html()用于设置元素的内容时,该元素中的任何内容都将被新内容完全替换。 此外,在使用新内容替换这些元素之前,jQuery会从子元素中删除其他构造(如数据和事件处理程序)。

强调我的。调用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);
        }
    });
    //...
});