为角度1.1.x中的ng-repeat编写的过滤器的$ digest迭代错误

zca*_*ate 9 javascript angularjs

我一直在寻找尝试编写过滤器,但它非常令人沮丧.

以下是我编写"chunk"过滤器时所遵循的几个资源

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

我试了一下并取得了一些成功.但发现版本之间的行为存在差异

生成$$ hashKey所描述的方法在1.1.5版本中不起作用.第一个小提琴很好,而第二个产生迭代错误,即使代码完全相同:

http://jsfiddle.net/nRGTX/38/ - 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"]]
Run Code Online (Sandbox Code Playgroud)

是否有任何变通方法/正确的方法来写这个?

Jam*_*ess 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;
}
Run Code Online (Sandbox Code Playgroud)

我还应该指出,您可以删除该defineHashKeys调用,因为我不认为它在此代码中有任何用途.我只留下它,因为它在你的原始代码中.当我删除它时似乎没有任何区别.