2

最近、KO マッピング プラグインを使用してページのデータを更新する際に気になる点がいくつかあります。最初のものは 2.1.1 で修正されたと思いますが、以下に示す 2 番目のものはまだ存在します。

私は単純なモデルを持っています。問題は、含まれているアドレスの配列にあります。マッピングプラグインを使用すると、実際には1つしかないのに、配列内の2つの要素を追跡しているようです。これが私のコードの問題なのか、マッピング プラグインの問題なのかはわかりません。次の簡単な例を考えてみてください。

//Retrieved thru AJAX
var serverData = { name: "Bob", Addresses: [{ AddressLine: "", City: "", PostalCode: "", StateID: 10}] };  

    load(serverData);  
    //Seems OK at this point
    //this.vm.__ko_mapping__.mappedProperties shows properties for Addresses[0] & name which makes sense


    //Now some time goes by and we want to update the bound VM w/ new data from the server
    load(serverData);  

    //Problem!
    //this.vm.__ko_mapping__.mappedProperties shows properties for Addresses[0] & Addresses[1]
    //But there is no Addresses[1]!!

    //Lets simulate an update of data (1 more time)
    load(serverData);
    //Interestingly it doesn't get any worse, still just Addresses[0] & Addresses[1]

    function load(d)
    {  
       if (this.vm) //Refresh existing VM
       {
          ko.mapping.fromJS(serverData, vm);
       }
       else    //On 1st Load have mapping create the VM and bind it
       {
          this.vm = ko.mapping.fromJS(serverData);   //Mapping creates object from server data
          ko.applyBindings(this.vm, $("body")[0]);
       }
    }
4

1 に答える 1

2

マッピング プラグインを使用すると、配列内の要素のキーを返すコールバックを定義できます。( http://knockoutjs.com/documentation/plugins-mapping.htmlの「キーを使用してオブジェクトを一意に識別する」を参照してください)。これは、オブジェクトが新しいか古いかを判断するために使用されます。次の 3 つの状態が考えられます。新しいオブジェクトが配列に追加される、既存の要素が配列に保持される (ただし更新される)、または既存の要素が新しいデータセットに存在しなくなったために配列から削除される。(これらの状態は、ユーティリティ関数 ko.utils.compareArrays によって実際に決定されます)

ここで正しい状態は「保持中」ですが、配列内のアドレスに一意のキーを提供していないため、マッピング プラグインはそれらのエントリが実際に同じであるという手がかりを持っていません。したがって、状態「削除」が現在のオブジェクトと状態を新しいオブジェクトに「追加」します。

これにより、注意が必要なすべての要素のリストが作成されます。現在のものにはキー「0」があり、新しいものにはキー「1」があるため、「mappedProperties」に奇妙なエントリがあります。これはバグと見なすことができると思いますが、非常に厄介です。また、ゴースト エントリの数は常に であるため、これは真のメモリ リークではありませんnumPreviousEntries

これは、一意のキーの使用(複数の行がない場合は何でもかまいません。したがって、状態IDを使用しました)が実際にこの問題を解決することを示すフィドルです:http://jsfiddle.net/xTHFg/4/

于 2012-04-22T14:45:44.343 に答える