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

时间:2014-04-15 11:07:54

标签: backbone.js backbone-views backbone-events 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()));
}
});

这是我的路由器

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

这是我的HTML,ID =' subSection'。

如果我签入控制台,我可以看到绑定到该视图的事件。

Object {change input: "inputChanged", change select: "selectionChanged", click input[type=submit]: "showModel"}

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

1 个答案:

答案 0 :(得分:5)

你的根本问题是你不正确地重复使用观点。

来自fine manual

  

<强> .empty()

     

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

所以当你说:

$("#subSection").empty();

您不仅要清除#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);
    }
});

如果您的观看次数需要额外清理,那么您可以覆盖remove来清理附加内容,然后链接到Backbone.View.prototype.remove.call(this)以调用默认remove

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

  

delegateEvents delegateEvents([events])

     

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

你会说:

$("#subSection").append(shareholderInfo.$el);
shareholderInfo.delegateEvents();

而不只是:

$("#subSection").append(shareholderInfo.$el);

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