AngularJS:ng-repeat 与动态列表,而不重建整个 DOM 树? [英] AngularJS: ng-repeat with dynamic list, without rebuilding entire DOM tree?

查看:20
本文介绍了AngularJS:ng-repeat 与动态列表,而不重建整个 DOM 树?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using ng-repeat on a table row with data from a JSON array retrieved from a server. My goal is to have the list update automatically whenever an item is added, removed, or modified on the server, without affecting the unmodified items. In the final implementation, these table rows will also contain bidirectionally bound <input> and <select> elements to send updates back to the server. Some of the available options in the <select> elements will also be generated using ng-repeat directives from another list that may also change.

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

So far, every time a new array comes from the server (currently polled every two seconds), the entire ng-repeat list is deleted and regenerated. This is problematic because it interferes with text selection, destroys input fields even if they are currently being edited by the user, and probably runs a lot more slowly than necessary.

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

I've written other web apps that do what I want using jQuery and DOM manipulation, but the code ends up being really hairy and development is time consuming. I'm hoping to use AngularJS and data binding to accomplish this in a fraction of the code and time.

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

So here's the question: is it possible to update the backing array this way, but only modify the DOM elements corresponding to the items/properties that actually changed?

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

Here's a minimal test case that simulates periodic polling using a hard-coded array in a timer (see it live at http://jsfiddle.net/DWrmP/). Notice that the text selection is cleared every 500ms due to the elements being deleted and recreated.

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

推荐答案

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

For those finding this from google, the page below describes a feature in AngularJS 1.2 that helps with this problem:

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

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

Edit to add: The most important sentences from the linked post, in case the link ever dies:

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

With the new "track by" syntax, I can now tell AngularJS which object property (or property path) should be used to associate a JavaScript object with a DOM node. This means that I can swap out JavaScript objects without destroying DOM nodes so long as the "track by" association still works.

这篇关于AngularJS:ng-repeat 与动态列表,而不重建整个 DOM 树?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆