2

手動サブスクリプションを呼び出した監視可能なプロパティの名前を見つける方法はありますか?

ノックアウトのコールバック署名は.subscribe(function(newValue) { ... }) 、オブジェクトのすべての監視可能なプロパティをサブスクライブしているため、次のような署名が必要です: function(newValue, propertyName)(そしておそらく古い値...)。

以下のコードの抜粋は、プロパティの周りにクロージャを取得しようとしているのを示していますが、最後にスキャンされたプロパティが常に表示されます。

変更されたプロパティを確認するにはどうすればよいですか?

this.Data = ko.mapping.fromJS(dataFromServer);

...

ScrollDataItem.prototype.GetInformedOnChange = function () {
    var self = this;
    for(var prop in this.Data) {
        if(self.Data.hasOwnProperty(prop) && prop != "__ko_mapping__") {
            var closureProp = prop;
            self.Data[prop].subscribe(function (newValue) {
                alert("New value is: " + newValue);
                alert("Property that called: " + closureProp);
            });
        }
    }
};
4

1 に答える 1

1

これが表示される理由は、ホイスト ( http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/ ) によるものです。宣言する ClosureProp 変数は、GetInformedOnChange 関数にスコープされます。forJavaScript の変数は、ループやループではなく、常に関数にスコープされwhileます。

あなたが見ているものを見てみましょう。

this.Data に FirstName と LastName の 2 つのプロパティがあるとします。初めてfor(var prop in this.Data)ループを通過するとき、prop は FirstName であるため、closureProp にはファースト ネームが割り当てられます。サブスクリプションはセットアップされますが、サブスクライブしているものがまだトリガーされていないため、closureProp はまだ何にも使用されていません。

2 回目のループでは、closureProp (同じ変数 - 新しい変数は作成されません - 巻き上げに関する上記のリンクを参照) が LastName に割り当てられ、LastName へのサブスクリプションが設定されます。

次に、FirstName サブスクリプションがトリガーされたと仮定すると、アラートを実行する匿名関数が呼び出されます。LastNameに割り当てられたclosurePropを使用します。

これは、スコープの追加レイヤー、つまり追加関数を追加することで修正できます。方法は次のとおりです。

スコープの追加レイヤーを提供するサブスクライブを処理する新しい関数を作成します。

function subscribeWithName(propName, observable) {
    var closureProp = propName;
    observable.subscribe(function(newValue) {
        alert("New value is: " + newValue);
        alert("Property that called: " + closureProp);
    });
}

この関数を呼び出して、サブスクリプションをセットアップします。

for(var prop in this.Data) {
    if(self.Data.hasOwnProperty(prop) && prop != "__ko_mapping__") {
        subscribeWithName(prop, self.Data[prop]);            
    }
}

ここにフィドルがあります:http://jsfiddle.net/tlarson/PfaD7/

于 2013-05-16T13:36:14.970 に答える