2013-02-19 35 views
22

Tôi có ba mô hình loại trực tiếp tương tự trong ứng dụng của mình và tôi muốn mở rộng mô hình cơ sở để kết hợp các đặc tính chung thay vì lặp lại bản thân ba lần.Knockout JS Model Inheritance

dụ

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

Tôi muốn sử dụng ItemModel như một lớp cơ sở và chỉ cần thêm các thuộc tính thêm khi cần thiết.

+0

OK, nhưng câu hỏi của bạn là gì? Bạn có vấn đề gì trong quá trình tạo lớp cơ sở? – nemesv

+0

câu hỏi của tôi là cách tiếp cận tốt nhất để làm điều này trong javascript là gì và nếu loại trực tiếp cung cấp một số tiện ích để đơn giản hóa nó. – BillPull

Trả lời

38

Tôi nghĩ rằng bạn có thể sử dụng ko.utils.extend như thế này

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

bên trong StandardItemModel

như thế này: http://jsfiddle.net/marceloandrader/bhEQ6/

+0

quá dễ dàng, cảm ơn! – Homer

+0

+1 cho một ví dụ fiddle –

+0

Liệu nó không mở rộng các thuộc tính ko.computed cùng với các thuộc tính ko.observable? –

-1

tôi đã thực hiện một cái gì đó tương tự, với rất nhiều thử và sai, nhưng tôi đã làm việc này cho tôi:

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

Sau đó bạn cần phải thêm một constructor prototyped:

StandardModel.prototype = new ItemModel(); 

Nếu bạn muốn có các phương pháp phổ biến, sau đó bạn cần phải thêm chúng vào các lớp cơ sở sử dụng nguyên mẫu để thêm chúng, sau đó gọi chúng trong lớp cao hơn bằng cách sử dụng:

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

Tạo một cá thể chỉ để thiết lập kế thừa là xấu. Đây là bài đăng giải thích lý do tại sao và cách khắc phục nó http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html –

+1

Cảm ơn! Tôi đã nhìn thấy mã như vậy (cũng như nhiều triển khai khác) khi đọc lên trên nó, nhưng không ai trong số họ giải thích nó đủ tốt cho tôi để thông báo. –

0

Tôi đoán bạn có thể làm một cái gì đó như thế này:

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

Bạn có thể chuỗi các cuộc gọi constructor sử dụng .call hoặc .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; 
} 

Các lợi thế hơn ko.utils.extend (hoặc các phương pháp tương tự từ jQuery, dấu gạch dưới, vv) được rằng bạn không tạo ra một đối tượng khác chỉ để lấy tham chiếu đến các phương thức của nó.