在backbone.js中重新渲染后未触发的事件

Jag*_*ags 1 backbone.js backbone-events backbone-views backbone-routing

我在重新渲染后尝试单击提交时遇到问题.

这是我的看法:

ShareHolderInfoView = Backbone.View.extend( {
template : 'shareholderinfo',
initialize: function() {
    this.model = new ShareHolderInfoModel();
},
render : function() {
    $.get("shareholderinfo.html", function(template) {
        var html = $(template);
        that.$el.html(html);
    });

    //context.loadViews.call(this);
    return this;
},
events:{
    "change input":"inputChanged",
    "change select":"selectionChanged",
    "click input[type=submit]":"showModel"
},
inputChanged:function(event){
    var field = $(event.currentTarget);
    var data ={};
    data[field.attr('id')] = field.val();
    this.model.set(data);
},
showModel:function(){
    console.log(this.model.attributes);
    alert(JSON.stringify(this.model.toJSON()));
}
});
Run Code Online (Sandbox Code Playgroud)

这是我的路由器

var shareholderInfo,  accountOwnerInfo;

App.Router = Backbone.Router.extend({

    routes:{
        'share':'share',
        'joint':'joint'
    },
    share:function(){

        $("#subSection").empty();
        if(!shareholderInfo){
            shareholderInfo = new ShareHolderInfoView();
            $("#subSection").append(shareholderInfo.render().el);
        } else{
            $("#subSection").append(shareholderInfo.$el);
        }
    },
    joint:function(random){
        $("#subSection").empty();
        if(!accountOwnerInfo){
            accountOwnerInfo = new AccountOwnerInfoView();
            $("#subSection").append(accountOwnerInfo.render().el);
        } else{
            $("#subSection").append(accountOwnerInfo.$el);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这是我的HTML一个id ='subSection'的div.

如果我在控制台中检查,我可以看到绑定到该视图的事件.

Object {change input: "inputChanged", change select: "selectionChanged", click input[type=submit]: "showModel"}
Run Code Online (Sandbox Code Playgroud)

但它没有调用showModel函数,我点击提交.请帮忙.

mu *_*ort 5

您的根本问题是您不正确地重复使用视图.

精细手册:

.empty()

描述:从DOM中删除匹配元素集的所有子节点.
[...]
为了避免内存泄漏,jQuery在删除元素本身之前从子元素中删除了其他构造,如数据和事件处理程序.

所以当你说:

$("#subSection").empty();
Run Code Online (Sandbox Code Playgroud)

你不仅要清除内容#subSection,还要删除附在内部的所有事件处理程序#subSection.特别是,您将删除任何绑定的事件处理程序accountOwnerInfo.elshareholderInfo.el(取决于哪个已经在内部#subSection).

重复使用视图通常比它的价值更麻烦,您的视图应该足够轻,以便您可以根据需要销毁和重新创建它们.破坏视图的正确方法是调用remove它.你可以重写你的路由器看起来更像这样:

App.Router = Backbone.Router.extend({
    routes: {
        'share':'share',
        'joint':'joint'
    },
    share: function() {
        this._setView(ShareHolderInfoView);
    },
    joint: function(random){
        this._setView(AccountOwnerInfoView);
    },
    _setView: function(view) {
        if(this.currentView)
            this.currentView.remove();
        this.currentView = new view();
        $('#subSection').append(this.currentView.render().el);
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您的视图需要任何额外的清理,那么您可以覆盖remove它们以清理额外内容然后链接Backbone.View.prototype.remove.call(this)到调用默认值remove.

如果由于某种原因你需要保持你的观点,你可以打电话delegateEvents给他们:

delegateEvents delegateEvents([events])

使用jQuery的on函数为视图中的DOM事件提供声明性回调.如果未直接传递事件哈希,则将其this.events用作源.

你会说:

$("#subSection").append(shareholderInfo.$el);
shareholderInfo.delegateEvents();
Run Code Online (Sandbox Code Playgroud)

而不只是:

$("#subSection").append(shareholderInfo.$el);
Run Code Online (Sandbox Code Playgroud)

我强烈建议您处理您的视图和廉价的短暂对象:销毁它们以将其从页面中删除,在需要进入页面时创建新的.