Knockout provides an elegant way of updating the user interface using Javascript View models. Javascript has an inheritance model. With that, we can create a hierarchy of classes. Consider the following HTML with Knockout bindings.
<div id="main"> <div data-bind="text: name"></div> <div data-bind="text: detail"></div> </div>
We use a simple Model class. Load it with data. And bind it to the HTML.
var model = new Model(); model.load(); ko.applyBindings(model, document.getElementById('main'));
Simple inheritance
Klaus Komenda has an article on Javascript inheritance. As an example, we inherit the Model
class from the BaseModel
class.
function BaseModel() { this.name = ko.observable(); } function Model() { this.detail = ko.observable(); } Model.prototype = new BaseModel();
BaseModel
has an observable named name. And Model
has an observable named detail. Since Model
inherits from BaseModel
, a Model object has both the name and detail observable properties.
Overriding functions
It is possible to override base class functions. Both BaseModel
and Model
classes define a load function. From the Model
class, we can invoke the load function of the BaseModel
class.
BaseModel.prototype.load = function () { this.name('a1'); }; Model.prototype.load = function () { // call base class method BaseModel.prototype.load.call(this); this.detail('a1 detail'); };
There is a good StackOverflow article that explains the benefits of declaring a function via prototypes.
Inheriting observable properties
Observable property in a Knockout View model is a function. All the objects of the derived classes share the same base class function. Any observable property defined in the base class is shared among multiple object instances.
In the above example, We create a collection of Model objects.
var model1 = new Model(); model1.name('a1'); var model2 = new Model(); model2.name('a2');
Both the Model
objects share the same value for the name observable. In this case, both models have the same name value of a2
. To overcome the problem, we use constructor inheritance as follows:
function Model() { var self = new BaseModel(); self.detail = ko.observable(); return self; }
If multiple instances of the derived class are required, use constructor inheritance rather than prototype inheritance.