34

我在表行上使用 ng-repeat,其中数据来自从服务器检索的 JSON 数组。我的目标是在服务器上添加、删除或修改项目时自动更新列表,而不会影响未修改的项目。在最终实现中,这些表行还将包含双向绑定<input><select>元素以将更新发送回服务器。元素中的一些可用选项<select>也将使用另一个列表中的 ng-repeat 指令生成,该列表也可能发生变化。

到目前为止,每次从服务器传来一个新数组(目前每两秒轮询一次),整个 ng-repeat 列表都会被删除并重新生成。这是有问题的,因为它会干扰文本选择,破坏输入字段,即使它们当前正在由用户编辑,并且可能运行得比必要的慢得多。

我已经编写了其他 Web 应用程序,它们使用 jQuery 和 DOM 操作来执行我想要的操作,但是代码最终变得非常繁琐,并且开发非常耗时。我希望使用 AngularJS 和数据绑定在一小部分代码和时间内完成此任务。

那么问题来了:是否可以通过这种方式更新后备数组,而只修改与实际更改的项目/属性相对应的 DOM 元素?


这是一个最小的测试用例,它使用计时器中的硬编码数组模拟定期轮询(在http://jsfiddle.net/DWrmP/上实时查看)。请注意,由于元素被删除和重新创建,文本选择每 500 毫秒被清除一次。

HTML

<body ng-app="myApp">
    <table ng-controller="MyController">
        <tr ng-repeat="item in items | orderBy:'id'">
            <td>{{item.id}}</td>
            <td>{{item.data}}</td>
        </tr>
    </table>
</body>

JavaScript

angular.module('myApp', []).controller(
    'MyController', [
        '$scope', '$timeout',
        function($scope, $timeout) {
            $scope.items = [
                { id: 0, data: 'Zero' }
            ];

            function setData() {
                $scope.items = [
                    { id: 1, data: 'One' },
                    { id: 2, data: 'Two' },
                    { id: 5, data: 'Five' },
                    { id: 4, data: 'Four' },
                    { id: 3, data: 'Three' }
                    ];
                $timeout(setData, 500);
            }
            $timeout(setData, 500);
        }
        ]
);
4

3 回答 3

38

对于那些从谷歌上找到这个的人,下面的页面描述了 AngularJS 1.2 中有助于解决这个问题的功能:

http://www.bennadel.com/blog/2556-Using-Track-By-With-ngRepeat-In-AngularJS-1-2.htm


编辑添加:链接帖子中最重要的句子,以防链接失效:

使用新的“track by”语法,我现在可以告诉 AngularJS 应该使用哪个对象属性(或属性路径)来将 JavaScript 对象与 DOM 节点相关联。这意味着只要“track by”关联仍然有效,我就可以在不破坏 DOM 节点的情况下交换 JavaScript 对象。

于 2014-01-15T21:18:10.313 回答
7

我相信这篇文章将解释 ngRepeat 的工作原理

http://www.bennadel.com/blog/2443-Rendering-DOM-Elements-With-ngRepeat-In-AngularJS.htm

因此,如果您将对象保存在集合中 - 那么是的(即 $hashKey persist )

否则 - 否

于 2013-06-13T05:07:15.010 回答
0

我计划最终自己构建以下解决方案,尽管它仍在我的产品积压中。

ng-repeat 的问题是它会在需要时从 DOM 中删除项目,因此对于表来说,这意味着它将调整大小等,但如果数据是动态的,它可能会闪烁,因为数据发生变化和表大小正在转变。特别是在分页期间,因为整个页面可能尚未加载。

为了避免这种闪烁,表格不能改变它的行数。取而代之的是“显示”数据的 ng-repeat,只需根据需要更改它,而无需从数组中添加或删除项目。

于 2016-04-17T04:45:17.437 回答