3

これが私の問題を示すjsFiddleです:http://jsfiddle.net/dDEd5/4/

要約すると、私は単純なViewModelを持っています:

ViewModel = function () {}
ViewModel.prototype = {
    child: function () {},
    children: new Array(3),

    outermethod: function () {
        this.innerMethod();
    },

    innerMethod: function () {
        alert("ok!");
    },

    outerProperty: function () {
        return this.innerProperty();
    },

    innerProperty: function() {
        return "Property is OK";
    }
}

'クリック'バインディングを使用してこのViewModelをバインドしようとしています。問題は、バインディングが$ parentコンテキストを使用する場合、ViewModel内の'this'の値がViewModelに解決されないことです。

たとえば、このバインディングは正常に機能します。

<div>
    <span data-bind="text: outerProperty()"></span>
    <button data-bind="click: outermethod">This Works</button>
</div>

ただし、別のバインディングコンテキストを使用し、$ parentを使用してViewModelを呼び出そうとすると、問題が発生します。次の2つの例では、プロパティは正常に解決されます。ただし、ボタンは両方ともエラーになります。

<div>
    <!-- ko with: child -->
    <span data-bind="text: $parent.outerProperty()"></span>
    <button data-bind="click: $parent.outermethod">This Doesn't</button>
    <!-- /ko -->
</div>

<div>
    <!-- ko foreach: children -->
    <span data-bind="text: $parent.outerProperty()"></span> 
        <button data-bind="click: $parent.outermethod">These Don't Either</button>
    <!-- /ko -->
</div>

私は、実行コンテキストがjavascriptでどのように機能するか、およびこれらの例が失敗する理由を理解しようと、デューデリジェンスを行いました。しかし、私はこれに途方に暮れています。

4

1 に答える 1

7

Knockout がハンドラーを実行すると、そのレベルでバインドされた現在のデータがコンテキストとして使用されます。したがって、$parentまたは$rootのようなものを使用すると、問題が発生する可能性があります。

それを処理するには、いくつかの方法があります。

-次のように、バインディング自体で適切なコンテキストにバインドできます。

`click: $parent.outermethod.bind($parent)`

これにより、確実$parentに になる新しい関数が返されますthis

-ビューモデルにバインドできます。プロトタイプに関数を配置しているため、もう少しやりがいがあります。

1 つの手法 (プロトタイプを使用しない) は、変数を使用して正しい値を追跡し、次のthisように関数で参照することです。

var ViewModel = function() {
  var self = this;

  this.outermethod = function() {
     self.innerMethod();
  };

};

プロトタイプを使用すると、プロトタイプに実装を配置してから、実際のインスタンスにバインドされたバージョンを次のように作成できます。

var ViewModel = function() {
   this.outermethod = this.outermethod.bind(this);
};

したがって、これにより、プロトタイプの関数の実装を正しいコンテキストで呼び出すインスタンスに新しい関数が作成されます。

于 2013-01-18T03:29:58.997 に答える