2012-04-23 42 views
7

Tôi đang sử dụng Knockout.js 2.0 và tôi đang cố gắng mở rộng nguyên mẫu hàm dựng mà tôi đã tạo bằng cách thêm một tính toán có thể quan sát được nhưng tự ném lên .IsSubDomain không phải là một hàm ". Làm thế nào để giải quyết lỗi này? Có cách nào khác để mở rộng một hàm xây dựng để giải quyết điều này?Thêm một tính toán có thể quan sát được qua nguyên mẫu vào hàm hàm dựng

http://jsfiddle.net/StrandedPirate/J44S4/3/

Lưu ý: Tôi biết tôi có thể xác định tính quan sát được bên trong đóng cửa hàm xây dựng của nhưng tôi đang xây dựng một bộ tạo mã tự động để xem loại trực tiếp mô hình và tôi cần để có thể mở rộng đối tượng của mình thông qua nguyên mẫu bất động sản.

+0

Tôi đoán nó không phải là dễ dàng có thể. Vấn đề là 'computed' là một hàm có chữ ký sau:' ko.computed (Func , Object) 'Trường hợp Object là một cá thể ** được chuyển vào ngữ cảnh' this' của hàm tính toán. – Oybek

+0

Tôi đã thử điều này quá nhưng nó không hoạt động: 'SiteModel.prototype.fullDomainName = ko.computed (function() { \t ... }, SiteModel.prototype);' Tôi cũng nhận thấy rằng hàm đang thực thi trong tải trang mà tôi nghĩ là trái tim của vấn đề. Nó chỉ nên thực hiện sau khi một thể hiện của đối tượng được tạo ra. Có cách nào để sửa đổi mã knockout để ngăn chặn thực hiện các chức năng trong kịch bản này? – TugboatCaptain

Trả lời

5

Tôi cũng answered this in the forum.

Dưới đây là một cách để làm điều đó (jsFiddle example):

<div data-bind="text: fullDomainName">test</div> 
<script> 
function SiteModel(rootUrl, data) { 
    var self = this; 
    self.rootUrl = rootUrl; 
    self.DomainName = ko.observable(data.DomainName); 
    self.IsSubDomain = ko.observable(data.IsSubDomain); 
    self.fullDomainName = ko.computed(self.fullDomainName, self); 
} 

SiteModel.prototype.fullDomainName = function() { 
    if (this.IsSubDomain() && this.DomainName()) { // bombs out here with "self.IsSubDomain is not a function" 
     return this.DomainName() + ".myCompanyWebsite.com"; 
    } 
    else { 
     return this.DomainName(); 
    } 
}; 

var temp = new SiteModel("someurl", { DomainName: "extraCool" }); 

ko.applyBindings(temp); 
</script> 

tôi đã xác định các chức năng trong các nguyên mẫu và làm cho nó một tính thể quan sát được trong các nhà xây dựng.

Đây là một cách để làm điều đó một cách chung chung hơn (jsFiddle example):

<div data-bind="text: fullDomainName">test</div> 
<script> 
Function.prototype.computed = function() { 
    this.isComputed = true; 
    return this; 
}; 
Object.prototype.makeComputeds = function() { 
    for (var prop in this) { 
     if (this[prop] && this[prop].isComputed) { 
      this[prop] = ko.computed(this[prop], this, {deferEvaluation:true}); 
     } 
    } 
}; 

function SiteModel(rootUrl, data) { 
    var self = this; 
    self.rootUrl = rootUrl; 
    self.DomainName = ko.observable(data.DomainName); 
    self.IsSubDomain = ko.observable(data.IsSubDomain); 
    self.makeComputeds(); 
} 

SiteModel.prototype.fullDomainName = function() { 
    if (this.IsSubDomain() && this.DomainName()) { // bombs out here with "self.IsSubDomain is not a function" 
     return this.DomainName() + ".myCompanyWebsite.com"; 
    } 
    else { 
     return this.DomainName(); 
    } 
}.computed(); 

var temp = new SiteModel("someurl", { DomainName: "extraCool" }); 

ko.applyBindings(temp); 
</script> 

Các cơ bản chức năng đọc của tính sẽ được chia sẻ qua các nguyên mẫu mặc dù tài sản tính thực tế sẽ không. Tôi cho rằng có thể có sự nhầm lẫn nếu bạn đã tạo một số đối tượng và sau đó thay đổi hàm trong nguyên mẫu. Các đối tượng mới sẽ sử dụng chức năng mới, nhưng các đối tượng cũ thì không.

Vì các quan sát được tính là các thuộc tính, bạn không nên mong đợi có thể thêm chúng vào các đối tượng hiện có thông qua mẫu thử nghiệm.

+1

Fiddle thứ hai của bạn có thể là một cách tốt để làm điều này, nhưng bên phải của bạn, tôi không nên cố gắng để thêm các thuộc tính cho nguyên mẫu họ nên ở lại chức năng constructor vì chúng sẽ được instanced. – TugboatCaptain

Các vấn đề liên quan