I have the following code:
switch (type) {
case "countdown":
this.render(_this.templates.countdown);
break;
case "timer":
this.render(_this.templates.timer);
if (App.Views.timer) App.Views.timer.remove();
App.Views.timer = new Timer();
break;
}
So, as I suppose when the template were rendered we're remove previous View, because the link on new DOM element changed. But I'm not sure what old view was really removed.
Because if I add console.log(App.Views.timer)
after if (App.Views.timer) App.Views.timer.remove();
I get: child {cid: "view3", $el: jQuery.fn.init(1), el: div#timer.timer}
. And it's look like nothing changed!
I have two questions.
remove
function do?View's remove
function just removes the element from the DOM while unbinding any DOM related events and Backbone specific events.
Removes a view and its
el
from the DOM, and callsstopListening
to remove any bound events that the view haslistenTo
'd.
The code for the remove
function is:
// Remove this view by taking the element out of the DOM, and removing any // applicable Backbone.Events listeners. remove: function() { this._removeElement(); this.stopListening(); return this; },
So it still lives in memory until you release any references left. Logging the view object to the console keeps it alive as it's a reference to it.
I wouldn't go your way on this. Instead of a switch case, you could use a Backbone Router with routes and then make yourself some kind of layout view.
A super simple layout view could look like this:
var LayoutView = Backbone.View.extend({
initialize: function() {
// caching the jQuery object on init
this.$content = this.$('#content');
},
setContent: function(view) {
var content = this.content;
if (content) content.remove();
content = this.content = view;
this.$content.html(content.render().el);
},
});
Used within a router:
var Router = Backbone.Router.extend({
routes: {
'about': 'aboutRoute',
'contact': 'contactRoute',
// put the catch-all last
'*home': 'homeRoute',
},
initialize: function() {
// create the layout once here
this.layout = new views.Application({
el: 'body',
});
},
homeRoute: function() {
var view = new views.Home();
this.layout.setContent(view);
},
aboutRoute: function() {
var view = new views.About();
this.layout.setContent(view);
},
contactRoute: function() {
var view = new views.Contact();
this.layout.setContent(view);
}
});
I wrote a detailed answer on how to use a router with a simple layout view.