私もフォーラムでこれに答えました。
これを行う 1 つの方法を次に示します ( jsFiddle の例)。
<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>
プロトタイプで関数を定義し、コンストラクターで計算されたオブザーバブルにしました。
これをより一般的な方法で行う方法を次に示します ( jsFiddle の例)。
<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>
実際の計算されたプロパティは共有されませんが、計算されたの基になる読み取り関数はプロトタイプを介して共有されます。いくつかのオブジェクトを作成してからプロトタイプの関数を変更すると、混乱が生じる可能性があると思います。新しいオブジェクトは新しい関数を使用しますが、古いオブジェクトは使用しません。
計算されたオブザーバブルはプロパティであるため、プロトタイプを介して既存のオブジェクトに追加できるとは思わないでください。