When an element is created, Knockback provides functions to auto-release ViewModels using Knockout's dispose node callback:
# binds a callback to the node that releases the view model when the node is removed using ko.removeNode ko.utils.domNodeDisposal.addDisposeCallback(node, -> kb.release(view_model) );
// binds a callback to the node that releases the view model when the node is removed using ko.removeNode
ko.utils.domNodeDisposal.addDisposeCallback(node, function() { kb.release(view_model)} );There are three ways to do this in Knockback:
# Auto-released Template
el = kb.renderTemplate('template_name', view_model, options)
# OR: When applying bindings
kb.applyBindings(view_model, el)
# OR: Manually
kb.releaseOnNodeRemove(view_model, el)
// Auto-released Template
var el = kb.renderTemplate('template_name', view_model, options);
// OR: When applying bindings
kb.applyBindings(view_model, el);
// OR: Manually
kb.releaseOnNodeRemove(view_model, el);This means you can use a Backbone.Router as follows and not need to explicitly call kb.release() because ko.removeNode calls it for you:
window.RouterBackboneJS = Backbone.Router.extend({
constructor: ->
Backbone.Router.prototype.constructor.apply(@, arguments)
loadPage = function(el) {
ko.removeNode(@active_el) if @active_el
$('body').append(@active_el = el)
$(el).addClass('active')
}
@route('', null, -> loadPage(kb.renderTemplate('home', new HomeViewModel())))
@route('things', null, -> loadUrl(kb.renderTemplate('things_page', new ThingsPageViewModel())))
@route('things/:id', null, (id) -> loadPage(kb.renderTemplate('thing_page', new ThingCellViewModel(things_collection.get(id)))))
})
window.RouterBackboneJS = Backbone.Router.extend({
constructor: function() {
var _this = this;
Backbone.Router.prototype.constructor.apply(this, arguments);
var loadPage = function(el) {
if (_this.active_el) {ko.removeNode(this.active_el); }
$('body').append(_this.active_el = el);
$(el).addClass('active');
}
this.route('', null, function() { loadPage(kb.renderTemplate('home', new HomeViewModel())); });
this.route('things', null, function() { loadPage(kb.renderTemplate('things_page', new ThingsPageViewModel())); });
this.route('things/:id', null, function(id) { loadPage(kb.renderTemplate('thing_page', new ThingCellViewModel(things_collection.get(id)))); });
}
});