【问题标题】:Backbone bind event when reload template重新加载模板时的主干绑定事件
【发布时间】:2015-10-02 10:36:06
【问题描述】:

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

谢谢。

【问题讨论】:

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


    【解决方案1】:

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

    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);
            }
        });
        //...
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多