最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - $digest iteration error for filters written for ng-repeat in angular 1.1.x - Stack Overflow

programmeradmin2浏览0评论

I've been looking into trying to write filters but its been quite frustrating.

Here are a couple of resources I was following for writing a 'chunk' filter

!topic/angular/IEIQok-YkpU !topic/angular/gEv1-YV-Ojg

I tried it out with some success. but found that there is difference in behaviour between versions

The methods described to produce a $$hashKey does not work in the 1.1.5 version. The first fiddle is fine, whilst the second produces in iteration error, even though the code is exactly the same:

/ - 1.0.3 version

/ - 1.1.5 version

 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"]]

Are there any workarounds/proper way to write this?

I've been looking into trying to write filters but its been quite frustrating.

Here are a couple of resources I was following for writing a 'chunk' filter

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

I tried it out with some success. but found that there is difference in behaviour between versions

The methods described to produce a $$hashKey does not work in the 1.1.5 version. The first fiddle is fine, whilst the second produces in iteration error, even though the code is exactly the same:

http://jsfiddle/nRGTX/38/ - 1.0.3 version

http://jsfiddle/nRGTX/39/ - 1.1.5 version

 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"]]

Are there any workarounds/proper way to write this?

Share Improve this question edited Jul 10, 2013 at 4:34 zcaudate asked Jul 10, 2013 at 4:10 zcaudatezcaudate 14.3k7 gold badges69 silver badges134 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 12 +50

Starting with version 1.1.4 the ng-repeat directive has a watch on the collection that you are iterating to make sure it hasn't changed. The way it works is that it pares every item in the array and if the items aren't equal (in the === sense), it thinks the collection has been updated. At least this is my understanding from having looked at the code.

If you were using a filter in the typical sense, where you are just returning a subset of the original items, then the items returned would be the same every time. However, because you're building a whole new structure, the items in the array are different every time (even though their content is the same), so the watch thinks the collection is constantly changing.

The only solution I could e up with was to create a cache of previously returned results. Every time the chunk filter is called, it checks to see if you've previously performed a filter with the same array and chunkSize. If so, it returns the cached result.

To do this, you should update your filter function to look something like this:

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;
}

I should also point out that you can probably remove the defineHashKeys call, because I don't think it serves any purpose in this code. I only left it in because it was in your original code. It didn't seem to make any difference when I removed it.

发布评论

评论列表(0)

  1. 暂无评论