ng-repeat渲染Ajax动态加载数组时重复显示的问题求助
我之前也碰到过一模一样的情况,第一次加载多少行,后面不管换什么数据都重复渲染同样的次数,简直让人抓狂!别担心,这几个实用的方法应该能帮你快速搞定:
直接替换数组引用,别在原数组上修改
很多人习惯先清空原数组再往里面塞新元素,比如写$scope.data.length = 0; $scope.data.push(...newData);,但这种操作有时候会让Angular的脏检查机制“误以为”数组还是原来的那个,导致DOM没有完全更新。更稳妥的做法是直接给$scope变量赋新的数组引用:// 假设你从Ajax请求拿到了新数据newData $scope.data = newData; // 如果担心引用问题,也可以用angular.copy创建副本 // $scope.data = angular.copy(newData);这样相当于给$scope.data换了个全新的“身份”,Angular能立刻识别到数组更新,重新渲染正确的行数。
给ng-repeat加上track by,明确元素标识
Angular的ng-repeat默认靠元素的引用和内容来追踪DOM元素,如果你的数据项没有唯一标识(比如id字段),或者新旧数组有内容重复的元素,Angular可能会错误复用旧的DOM元素,导致重复渲染。解决办法很简单,在ng-repeat里加上track by:<!-- 如果数据项有唯一id(推荐用这个) --> <tr ng-repeat="item in data track by item.id"> <!-- 表格单元格内容 --> </tr> <!-- 如果没有唯一id,临时用$index(注意:数组元素顺序变化时可能有副作用) --> <tr ng-repeat="item in data track by $index"> <!-- 表格单元格内容 --> </tr>加上track by后,Angular就能精准对应每个数据项和DOM元素,不会再乱渲染了。
确保Ajax回调触发Angular的脏检查
如果你用的是原生XMLHttpRequest或者jQuery的$.ajax,而不是Angular自带的$http服务,赋值操作可能不会自动触发Angular的脏检查循环,导致视图没及时更新。这时候要把赋值操作包在$scope.$apply()里:// 举个jQuery ajax的例子 $.get('/your-api-url', function(newData) { $scope.$apply(function() { $scope.data = newData; }); });当然更推荐直接用Angular的$http服务,它会自动处理脏检查,省掉不少麻烦:
$http.get('/your-api-url').then(function(response) { $scope.data = response.data; });
你可以先试试前两个方法,大部分情况下这俩就能解决问题啦!
内容的提问来源于stack exchange,提问作者Angel Montilla

