2012-10-03 8 views
10

Knockout.jsのデフォルトの等価比較子が、非プリミティブ型を等しくないものとして扱うのはなぜですか?ノックアウトバージョン2.1.0デバッグソースコードから

ko.observable['fn'] = { 
    "equalityComparer": function valuesArePrimitiveAndEqual(a, b) { 
     var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes); 
     return oldValueIsPrimitive ? (a === b) : false; 
    } 
}; 

これは私にはわかりにくいようだが、スティーブサンダーソンは、これを定義するために彼の方法から出て行ったいくつかの理由がなければなりません。なぜこれが当てはまるのでしょうか?変更通知が不必要にトリガーされているようです。

+0

大きな質問です! 私はちょうど十分なKOを理解していないかもしれませんが、上記のコードはどのように変更通知をトリガーしますか? –

答えて

4

これは、オブジェクトを保持するオブザーバブルを持っている場合、サブプロパティが変更されたかどうかをKnockoutは知らないからです。

この時点で、オブジェクトのプロパティの1つが変更された場合に備えて通知がトリガーされます。

+0

観測値が同じ値で再び設定された場合にのみ役立ちますか?例えば。もしあなたが 'var obj = {name: 'David'}; var x = ko.observable(obj); '次に、' obj.name = 'Bob';と言うと、 'x(obj);を呼び出した場合にのみ通知をトリガーします。正しい? – Davy8

+0

そうです、それは正しいです。また、 'x.valueHasMutated()'を呼び出すこともできます –

+3

私にとってはかなり限定されたユースケースのように思えますが、私にとっては理解できないソースコードを調べなければならないという予期しない動作です。これはKOの使用で多く発生した問題でしたか?通常の平等チェックのように思えるのは、オブジェクトの平等性がどのように機能するかを理解していない人にとって問題になるだけです。 – Davy8

0

オブジェクトを保持しているオブザーバブルがある場合は、カスタムequalityComparerを作成して、必要に応じて等価を返すことができます。カスタマイズしたいオブザーバブルインスタンスにプロパティを設定するだけです。署名は次のとおりです。

myObservable["equalityComparer"] = function(a, b){ 
    return a===b;// Or any arbitrary comparison 
}; 

今、あなたの観察可能な唯一の関数がfalseを返す場合は、変更イベントを発生させています。

関連する問題