0

どうか、誰かがこれを手伝ってくれますか?

createメソッドを実行すると、次のエラーが発生します。

*Uncaught TypeError: Object #<Object> has no method 'baseUri'*

このメソッドは、次のバインディングから呼び出されます。

<form id="createProducts" data-bind="submit: products.create">

PreLoadメソッドから呼び出されるreadメソッドが実行されると、baseUriとitemsの両方が使用可能なります

ビューモデルが関数として定義されている場合、この問題の解決策を見つけましたが、私の場合は、オブジェクトとして定義されています。

これは私の完全なJSファイルです


var mm = {

    /* Products ********************************************************** */

    products: {

        items: ko.observableArray([]),

        read: function () {
            $.getJSON(this.baseUri(), this.items);
        },

        create: function (formElement) {

            $.post(this.baseUri(), $(formElement).serialize(), null, "json")
                .done(function (o) {                    
                    alert("The Product " + o.Name + " was created.");
                    this.items.push(o);
                });
        },

        baseUri: function () { return BASE_URI; }
    }

};

function PreLoad() {

    mm.products.read();

    ko.applyBindings(mm);
}

  • BASE_URIはマスターページで定義されたグローバル変数です。ネストされたビューモデルが複数あり(このコードから切り取ったものです)、各baseUriはBASE_URI+"some_string_value"の合成であるため必要です。とにかく、リストに表示されている値を更新するには、アイテムにもアクセスする必要があります。

ありがとう!

4

3 に答える 3

0

Andrew Whitakerがすでに述べたように、「これ」はあなたが期待している文脈ではありません。私の解決策は、「this」参照(たとえば「self」と呼ばれる)を保存し、「this」の代わりにそれを使用することです。

products: {
    self: undefined,
    items: ...,
    init: function() { 
        this.self = this; 
    },
    read: function () {$.getJSON(self.baseUri(), self.items);},
    create: function () {
        $.post(self.baseUri(), $(formElement).serialize(), null, "json")
            .done(function (o) {                    
                alert("The Product " + o.Name + " was created.");
                self.items.push(o);
            });
    },
    baseUri: function () { return BASE_URI; }
};

function PreLoad() {

    mm.products.init();
    mm.products.read();

    ko.applyBindings(mm);
}

また、どのコンテキストで関数を呼び出す必要があるかを明示的に示すこともできます。

<form id="createProducts" data-bind="submit: function () { products.create($root.products); }">

products: {
    create: function(self) {
        ...
    }

その場合、$ rootはビューモデルを指す必要があるため、productsオブジェクトのインスタンスを渡して関数を作成します。

于 2012-11-19T08:54:18.407 に答える
0

電話をかけたときの気持ちthisとは違う気がしますproducts.create.bindを使用してコンテキストを明示的に設定してみてください。

<form id="createProducts" data-bind="submit: products.create.bind($data)">
于 2012-11-19T01:57:28.117 に答える
0

thisイベントをバインドするときにそれが正しいことを確認する2つの方法があります。

最初は使用することbindです:

<form id="createProducts" data-bind="submit: products.create.bind(products)">

2つ目は、インライン関数を使用することです。

<form id="createProducts" data-bind="submit: function() { products.create(); }">

おそらく、この動作は将来変更される可能性があります(https://github.com/SteveSanderson/knockout/issues/378を参照)。

編集

thisコールバック関数で使用できるようにするための2つの解決策があります。1つ目は、クロージャーを介して使用できるローカル変数にコピーthisすることです。

        var self = this;
        $.post(this.baseUri(), $(formElement).serialize(), null, "json")
            .done(function (o) {                    
                alert("The Product " + o.Name + " was created.");
                self.items.push(o);
            });

bind2つ目は、コールバック関数で使用することです。

        $.post(this.baseUri(), $(formElement).serialize(), null, "json")
            .done(function (o) {                    
                alert("The Product " + o.Name + " was created.");
                this.items.push(o);
            }.bind(this));
于 2012-11-19T21:22:53.947 に答える