I have three relatively similar knockout models in my application and I would like to extend a base model to combine common properties rather than repeat myself three times.
example
var ItemModel = function (item) {
var self = this;
self.order = ko.observable(item.order);
self.title = ko.observable(item.title);
self.price = ko.observable(item.price);
self.type = ko.observable(item.type);
};
var StandardItemModel = function (item, cartItemTypes) {
var self = this;
self.order = ko.observable(item.order);
self.title = ko.observable(item.title);
self.price = ko.observable(item.price);
self.type = ko.observable(item.type);
self.isInCart = ko.computed(function () {
return cartItemTypes().indexOf(item.type) > -1;
}, self);
self.itemClass = ko.computed(function () {
return self.isInCart() ? "icon-check" : "icon-check-empty";
}, self);
};
var CustomItemModel = function (item) {
var self = this;
self.order = ko.observable(item.order);
self.title = ko.observable(item.title);
self.price = ko.observable(item.price);
self.type = ko.observable(item.type);
self.icon = item.icon;
};
I would like to use ItemModel as a base class and just add the extra properties as necessary.
I think you can use ko.utils.extend like this
ko.utils.extend(self, new ItemModel(item));
inside the StandardItemModel
like this: http://jsfiddle.net/marceloandrader/bhEQ6/
I guess you can do something like this:
var StandardItemModel = function (item, cartItemTypes) {
var self = this;
self.standard = new ItemModel(item);
self.isInCart = ko.computed(function () {
return cartItemTypes().indexOf(item.type) > -1;
}, self);
self.itemClass = ko.computed(function () {
return self.isInCart() ? "icon-check" : "icon-check-empty";
}, self);
}
function MyBaseType() {
var self = this;
self.Id = 1
}
function MyComplexType() {
var self = this;
//Extending this class from MyBaseType
ko.utils.extend(self, new MyBaseType());
self.Name = 'Faisal';
self.MyComplexSubType = new MyComplexSubType();
}
function MyComplexSubType() {
var self = this;
self.Age = 26;
}
JSFIDDLE EXAMPLE
I've done something similar, with a lot of trial and error, but I got this to work for me:
var StandardItemModel = function (item, cartItemTypes) {
var self = this;
ItemModel.call(self, item)
}
You then need to add a prototyped constructor:
StandardModel.prototype = new ItemModel();
If you want to have common methods, then you need to add them to the base classes using prototype to add them, then call them in the higher class using:
ItemModel.prototype.methodName.call(self, parameters);
You can chain constructor calls using .call or .apply
function ItemModel (item) {
var self = this;
self.order = ko.observable(item.order);
self.title = ko.observable(item.title);
self.price = ko.observable(item.price);
self.type = ko.observable(item.type);
}
function StandardItemModel(item, cartItemTypes) {
var self = this;
ItemModel.call(this, item);
self.isInCart = ko.computed(function () {
return cartItemTypes().indexOf(item.type) > -1;
}, self);
self.itemClass = ko.computed(function () {
return self.isInCart() ? "icon-check" : "icon-check-empty";
}, self);
}
function CustomItemModel (item) {
var self = this;
ItemModel.apply(this, [item]);
self.icon = item.icon;
}
The advantage over ko.utils.extend
(or similar methods from jQuery, underscore, etc) is that you are not creating an additional object just to grab references to its methods.