1

I am facing a problem while trying to click submit after re-render.

This is my view:

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

This is my Router

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

This is my HTML a div with id='subSection'.

if I check in console, I can able to see the events bound to that view.

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

But its not calling that showModel function afer i click submit. Please help.

Juozas Kontvainis
  • 9,461
  • 6
  • 55
  • 66
Jags
  • 65
  • 1
  • 8

1 Answers1

5

Your fundamental problem is that you're improperly reusing views.

From the fine manual:

.empty()

Description: Remove all child nodes of the set of matched elements from the DOM.
[...]
To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves.

So when you say:

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

you're not just clearing out the contents of #subSection, you're also removing all event handlers attached to anything inside #subSection. In particular, you'll remove any event handlers bound to accountOwnerInfo.el or shareholderInfo.el (depending on which one is already inside #subSection).

Reusing views is usually more trouble than it is worth, your views should be lightweight enough that you can destroy and recreate them as needed. The proper way to destroy a view is to call remove on it. You could rewrite your router to look more like this:

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

If your views need any extra cleanup then you can override remove on them to clean up the extras and then chain to Backbone.View.prototype.remove.call(this) to call the default remove.

If for some reason you need to keep your views around, you could call delegateEvents on them:

delegateEvents delegateEvents([events])

Uses jQuery's on function to provide declarative callbacks for DOM events within a view. If an events hash is not passed directly, uses this.events as the source.

and you'd say things like:

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

instead of just:

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

I'd strongly recommend that you treat your views and cheap ephemeral objects: destroy them to remove them from the page, create new ones when they need to go on the page.

mu is too short
  • 426,620
  • 70
  • 833
  • 800