2012-04-23 5 views
7

Używam Knockout.js 2.0 i próbuję rozszerzyć prototyp konstruowanej przeze mnie funkcji konstruktora, dodając obliczone obserwowalne, ale wyrzucając "ja" .IsSubDomain nie jest funkcją ". Jak rozwiązać ten błąd? Czy istnieje inny sposób na rozszerzenie funkcji konstruktora, aby rozwiązać ten problem?Dodawanie obliczonego obserwowalnego za pośrednictwem prototypu do funkcji konstruktora

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

Uwaga: Wiem, że mógłbym zdefiniować obliczany zaobserwować wewnątrz zamknięcia funkcji konstruktora, ale buduję automatycznego generatora kodu dla widoku nokaut modeli i muszę być w stanie rozszerzyć moje przedmiotów przez prototypu własność.

+0

Myślę, że to nie jest takie łatwe. Chodzi o to, że "obliczony" jest funkcją, która ma następującą sygnaturę: 'ko.computed (Func , Object)' Where Object jest ** instancją **, która jest przekazywana do kontekstu funkcji 'this' funkcji obliczeniowej. – Oybek

+0

Próbowałem również, ale to nie działa: 'SiteModel.prototype.fullDomainName = ko.computed (function() { \t ... }, SiteModel.prototype);" Zauważyłem również, że funkcja jest wykonywana podczas ładowanie strony, które według mnie stanowi sedno problemu. Powinien on zostać wykonany dopiero po utworzeniu instancji obiektu. Czy istnieje sposób modyfikowania kodu typu knockout, aby uniemożliwić wykonanie funkcji w tym scenariuszu? – TugboatCaptain

Odpowiedz

5

Ja także answered this in the forum.

Oto jeden ze sposobów, aby to zrobić (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> 

Mam zdefiniowano funkcję w prototypie i uczynił z niego obliczane obserwowalne w konstruktorze.

Oto sposób na to sposób bardziej ogólny (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> 

Podstawowa odczytać funkcją komputerowej będzie zostać udostępniony poprzez prototyp chociaż rzeczywista własność komputerowej nie będzie. Przypuszczam, że może wystąpić zamieszanie w postaci , jeśli utworzyłeś jakieś obiekty, a następnie zmieniłeś prototyp w funkcji . Nowe obiekty używałyby nowej funkcji, ale stare obiekty nie byłyby.

Skoro obliczone obserwowalne są właściwościami, nie można oczekiwać, że będą one mogły dodać je do istniejących obiektów za pośrednictwem prototypu.

+1

Twoje drugie skrzypce może być dobrym sposobem na zrobienie tego, ale twoje prawo, nie powinienem próbować dodawać właściwości do prototypu, powinny one pozostać w funkcji konstruktora, ponieważ będą instancjami. – TugboatCaptain