2013-02-19 19 views
22

Mam trzy stosunkowo podobne modele nokautu w mojej aplikacji i chciałbym rozszerzyć model podstawowy, aby połączyć wspólne właściwości, a nie powtarzać się trzy razy.Knockout JS Model Inheritance

przykład

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; 
}; 

Chciałbym użyć ItemModel jako klasy bazowej i po prostu dodać dodatkowe właściwości, jak to konieczne.

+0

OK, ale jakie jest twoje pytanie? Jakie masz problemy podczas tworzenia klasy bazowej? – nemesv

+0

moje pytanie jest najlepsze podejście do tego w javascript i jeśli nokaut zapewnia pewne narzędzie do uproszczenia go. – BillPull

Odpowiedz

38

myślę, że można użyć ko.utils.extend jak ten

ko.utils.extend(self, new ItemModel(item)); 

wewnątrz StandardItemModel

jak ten: http://jsfiddle.net/marceloandrader/bhEQ6/

+0

zbyt łatwe, dzięki! – Homer

+0

+1 za przykład skrzypiec –

+0

Czy nie rozszerza atrybutów ko.computed wraz z ko.observable? –

-1

robiłem coś podobnego, z dużą ilością prób i błędów, ale mam to, aby pracować dla mnie:

var StandardItemModel = function (item, cartItemTypes) { 
    var self = this; 
    ItemModel.call(self, item) 
} 

Następnie należy dodać prototyp konstruktora:

StandardModel.prototype = new ItemModel(); 

Jeśli chcesz mieć wspólne metody, musisz dodać je do klas podstawowych za pomocą prototypu, aby je dodać, a następnie wywołać w wyższej klasie, używając:

ItemModel.prototype.methodName.call(self, parameters); 
+1

Tworzenie instancji tylko w celu ustawienia dziedziczenia jest złe. Oto post wyjaśniający, dlaczego i jak to naprawić http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html –

+1

Dzięki! Widziałem taki kod (jak również wiele innych implementacji) podczas czytania tego, ale żaden z nich nie wyjaśnił tego wystarczająco dobrze, abym mógł go zauważyć. –

0

Myślę, że można zrobić coś takiego:

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); 
} 
0
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

-1

Można łańcuchu połączenia konstruktor używając .Połączenia lub .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; 
} 

przewagę nad ko.utils.extend (lub podobnych metod z jQuery, podkreślenia itp) jest to, że nie tworzą dodatkowy przedmiot po prostu chwycić odniesienia do jego metod.