Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone bind multi event to one button after i new View multi times

Tags:

backbone.js

var UserView = Backbone.View.extend({
        initialize: function(){
            MData.blankHeader.data.topBar.title = '<h1 id="titleLogo">' + this.options.userName + '</h1>';
            MData.blankHeader.data.topBar.btn1 = '';
            MData.blankHeader.data.topBar.btn2 = '<a href="#" id="sendDm" class="cu-round-btn">发私信</a>';
            $('header').html(Mustache.to_html($('#headerTpl').html(), MData.blankHeader)).append('<div class="topbar-shadow"></div>'); 
            $('footer').html(Mustache.to_html($('#footerTpl').html(), MData.eventlistFooter)).attr('id','').find('.selected').removeClass('selected').end().find('.footer-item:eq(3)').addClass('selected');
            $('#content').css({"top": $('header').height() + 'px'});
            setTimeout(function(){
                scrollinit(); 
            },0);
            onScrollEnd = true;//??
            this.render();
        },

        events:{
            "click #sendDm" : "sendDm"
        },

        el: $('body'),

        sendDm: function(e){
            alert('send dm');
            e.preventDefault();
        },

        render: function(){
            var html = "";
            html += Mustache.to_html($("#userTpl").html(), this.options.userData);
            $('#pullDown').css("display","none");
            $('#ajaxEvent').html(html);
            console.log(this.options.userId);
            if(this.options.userName != "me"){
                $('#dm').remove();
            }
            calTime();
            function calTime(){
                _.each($('.user-timeStamp'), function(date){
                    $(date).html(humaneDate(date.innerHTML));
                });
            }
            setInterval(calTime,60000)
            return this;
        }
    });   



//code in Router
    var newUser = new UserCol();//new a Collection
                    newUser.fetch({
                        data: param,
                        success: function(model,data){
                            new UserView({userData: data, userId: param})
                        }
                    })

So when I view this page multi times(change the param in the address bar),the backbone will new the UserView multi times,and the event bind to to button will fire multi time, How Can I make the button just fire one time.

like image 837
eddie yang Avatar asked Aug 19 '11 17:08

eddie yang


1 Answers

you have a memory leak and zombie view objects

events in a backbone view are scoped to the el that is specified (or generated for you). since you have specified the el as body, the click #sendDm event will find any instance of an element with an id of sendDm.

when you change the route in the url, the router is picking up the change and loading up the view... however the old view is never being closed or removed properly, so you are left with a zombie view object hanging around in memory, bound to the click event of the #sendDm element. every time you move to a new route and load another view up, you're leaving behind another zombie form, bound to that element.

do not specify body as your el. also - don't call this.render() from your view's initialize method. instead, have your router handle the knowledge of body and have it render the view, while also removing old views:

var newUser = new UserCol();//new a Collection

MyRouter = Backbone.Router.extend({
  routes: {"some/route/:id": "showIt"},

  initialize: function(){
    _.bindAll(this, "showUser");
  }

  showIt: function(id){
    newUser.fetch({
      data: param,
      success: this.showUser
    });
  },

  showUser: function(model,data){
    if (this.userView){
      this.userView.unbind();
      this.userView.remove();
    }
    var view = new UserView({userData: data, userId: param});
    view.render();
    $('body').html(view.el);
    this.userView = view;
  }
});
like image 144
Derick Bailey Avatar answered Oct 22 '22 09:10

Derick Bailey