2013-07-10 4 views
9

私はフィルタを書き込もうとしていますが、かなりイライラしています。ここで

は、私はある程度の成功を収めて、それを試してみた私は

https://groups.google.com/forum/#!topic/angular/IEIQok-YkpU https://groups.google.com/forum/#!topic/angular/gEv1-YV-Ojg

「チャンク」フィルタを作成するため、次のされたリソースのカップルです。バージョン間の動作に違いがあることが判明しました

$$ hashKeyを生成するために記述されているメソッドは、1.1.5バージョンでは機能しません。 - 1.0.3バージョン

http://jsfiddle.net/nRGTX/39/ - 1.1.5バージョン

Error: 10 $digest() iterations reached. Aborting! 
Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 16; oldVal: 14"],["fn: $watchCollectionWatch; newVal: 18; oldVal: 16"],["fn: $watchCollectionWatch; newVal: 20; oldVal: 18"],["fn: $watchCollectionWatch; newVal: 22; oldVal: 20"],["fn: $watchCollectionWatch; newVal: 24; oldVal: 22"]] 

http://jsfiddle.net/nRGTX/38/:第二は、繰り返しエラーで生成しながら、最初のバイオリンは、コードがまったく同じであっても、結構なのですが、これを書くための回避策/適切な方法はありますか?

答えて

12

バージョン1.1.4から、ng-repeatディレクティブには、変更されていないことを確認するために反復処理しているコレクションのウォッチがあります。それが動作する方法は、配列内のすべての項目を比較し、項目が等しい場合(===の意味で)、コレクションが更新されたとみなします。少なくともこれはコードを見たことによる私の理解です。

通常の意味でフィルタを使用していた場合、元のアイテムのサブセットを返すだけの場合、返されるアイテムは毎回同じになります。しかし、新しい構造体を構築しているので、配列内の項目は毎回異なります(内容は同じですが)ので、コレクションは常に変化していると見なします。

私が思い付く唯一の解決策は、以前に返された結果のキャッシュを作成することでした。チャンクフィルタが呼び出されるたびに、以前に同じ配列とchunkSizeでフィルタを実行したかどうかを確認します。そうであれば、キャッシュされた結果を返します。

これを行うには、このような何かを見て、あなたのフィルタ機能を更新する必要があります。

return function(array, chunkSize) { 
    if (!(array instanceof Array)) return array; 
    if (!chunkSize) return array; 

    // Create empty cache if it doesn't already exist. 
    if (typeof myApp.chunkCache === "undefined") { 
    myApp.chunkCache = []; 
    } 

    // Search the cache to see if we filtered the given array before. 
    for (var i = 0; i < myApp.chunkCache.length; i++) { 
    var cache = myApp.chunkCache[i]; 
    if (cache.array == array && cache.chunkSize == chunkSize) { 
     return cache.result; 
    } 
    } 

    // If not, construct the chunked result. 
    var result = chunkArray(array, chunkSize); 
    defineHashKeys(result); 

    // And then add that result to the cache. 
    var cache = { 
    array: array, 
    chunkSize: chunkSize, 
    result: result 
    }; 
    myApp.chunkCache.push(cache); 

    return result; 
} 

私も、私はそれが任意のに役立つとは思わないので、あなたはおそらく、defineHashKeys呼び出しを削除することができますことを指摘すべきですこのコードで目的としています。元のコードになっていたので、残しておきました。私はそれを取り除いても何の違いもないようです。

+0

ありがとうございました!キャッシュでは、ページに複数のチャンクフィルタがあるとどうなりますか?私はここで少し試行しましたhttp://jsfiddle.net/nRGTX/42/それは2つのチャンクフィルターのために働くようですが、なぜ私はフィルターが互いに絡み合うことを期待していたのでしょうかと疑問に思っています。 – zcaudate

+0

複数のフィルタでテストしました。そのようなソリューションは、そのように動作するように設計されていました。キャッシュは、arrayとchunkSizeの組み合わせごとに別々のエントリを格納するので、異なるサイズまたは異なる配列を持つ2つのフィルタが競合しないように注意してください。 –

関連する問題