You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selectize报错:已达到10次$digest()迭代,请求排查解决

解决Selectize结合AngularJS过滤数组时的10 $digest() iterations reached错误

问题场景

我在项目中使用Selectize下拉框:

<selectize config="mySelectizeConfig" options="getAvailableObjects(id)"></selectize>

控制器中直接返回数组时运行完全正常:

$scope.getAvailableObjects=function(id) { 
  return $scope.available_objects[id] 
}

但一旦对数组做过滤处理,就会触发Error: 10 $digest() iterations reached. Aborting!的报错:

$scope.getAvailableObjects=function(id) { 
  var result = []; 
  result = $scope.available_objects[id].filter(function(object) { 
    return object.is_active; 
  }); 
  return result; 
}

错误根源

AngularJS的脏值检测机制是靠对比值的引用地址来判断数据是否变化的。你每次调用filter方法,都会返回一个全新的数组对象——哪怕数组里的内容和上一次完全一样,Angular都会认为这个值发生了变化,于是会再次触发$digest循环去验证。这个过程会反复触发,直到达到框架设定的10次上限,就抛出了这个错误。

解决方案

下面给你几个实用的解决思路,按推荐程度排序:

方案1:缓存过滤后的结果(最推荐)

在控制器里维护一个缓存对象,只在源数据或者过滤条件变化时重新执行过滤,避免每次调用都生成新数组:

// 初始化缓存容器
$scope.filteredObjectsCache = {};

// 深度监听源数据变化,更新缓存
$scope.$watch('available_objects', function(newData) {
  if (!newData) return;
  
  // 遍历所有id对应的数组,预过滤并缓存结果
  Object.keys(newData).forEach(function(id) {
    $scope.filteredObjectsCache[id] = newData[id].filter(function(item) {
      return item.is_active;
    });
  });
}, true); // 第三个参数true表示深度监听对象内部的变化

// 修改方法直接返回缓存的结果
$scope.getAvailableObjects = function(id) {
  return $scope.filteredObjectsCache[id] || [];
};

方案2:结合track by优化(视Selectize支持情况)

如果你的Selectize指令支持Angular的track by语法,可以在模板中添加这个规则,帮助Angular识别数组项的唯一性,减少不必要的脏检查:

<selectize config="mySelectizeConfig" options="item in getAvailableObjects(id) track by item.id"></selectize>

注意:这个方案的有效性取决于Selectize指令对Angular语法的兼容程度,如果指令内部没处理track by,可能需要搭配方案1一起使用。

方案3:记忆化过滤函数

用记忆化(memoization)技术缓存相同输入的过滤结果,避免重复计算:

// 实现一个简单的记忆化工具函数
function memoize(func) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (!cache[key]) {
      cache[key] = func.apply(this, args);
    }
    return cache[key];
  };
}

// 把过滤函数包装成记忆化版本
$scope.getAvailableObjects = memoize(function(id) {
  if (!$scope.available_objects[id]) return [];
  return $scope.available_objects[id].filter(function(item) {
    return item.is_active;
  });
});

// 记得在源数据变化时清空缓存,保证数据更新
$scope.$watch('available_objects', function() {
  $scope.getAvailableObjects.cache = {};
}, true);

总结

核心问题就是每次过滤都生成新数组导致Angular脏检查陷入循环,只要让返回的数组引用在内容不变时保持一致,就能解决这个问题。优先推荐方案1,逻辑清晰且易于维护,适合绝大多数场景。

内容的提问来源于stack exchange,提问作者Petran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:55:24