7

私は Knockout.js 2.0 を使用しており、計算されたオブザーバブルを追加して作成したコンストラクター関数のプロトタイプを拡張しようとしていますが、「self.IsSubDomain は関数ではありません」をスローします。このエラーを解決するにはどうすればよいですか? これを解決するためにコンストラクター関数を拡張する別の方法はありますか?

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

注: コンストラクター関数のクロージャー内で計算されたオブザーバブルを定義できることはわかっていますが、ノックアウト ビュー モデル用の自動コード ジェネレーターを構築しているため、prototype プロパティを介してオブジェクトを拡張できる必要があります。

4

1 に答える 1

5

私もフォーラムでこれに答えました

これを行う 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>

実際の計算されたプロパティは共有されませんが、計算されたの基になる読み取り関数はプロトタイプを介して共有されます。いくつかのオブジェクトを作成してからプロトタイプの関数を変更すると、混乱が生じる可能性があると思います。新しいオブジェクトは新しい関数を使用しますが、古いオブジェクトは使用しません。

計算されたオブザーバブルはプロパティであるため、プロトタイプを介して既存のオブジェクトに追加できるとは思わないでください。

于 2012-04-28T02:22:02.017 に答える