Pregunta AngularJS: ng-repeat con lista dinámica, sin reconstruir todo el árbol DOM?


Estoy usando ng-repeat en una fila de la tabla con datos de una matriz JSON recuperada de un servidor. Mi objetivo es que la lista se actualice automáticamente cada vez que se agrega, elimina o modifica un elemento en el servidor, sin afectar los elementos no modificados. En la implementación final, estas filas de la tabla también contendrán enlaces bidireccionales <input> y <select> elementos para enviar actualizaciones al servidor. Algunas de las opciones disponibles en <select> también se generarán elementos utilizando las directivas ng-repeat de otra lista que también pueden cambiar.

Hasta ahora, cada vez que una nueva matriz proviene del servidor (actualmente sondeada cada dos segundos), toda la lista ng-repeat se borra y se regenera. Esto es problemático porque interfiere con la selección de texto, destruye los campos de entrada incluso si el usuario los edita actualmente y probablemente se ejecute mucho más lentamente de lo necesario.

He escrito otras aplicaciones web que hacen lo que quiero usando la manipulación de jQuery y DOM, pero el código termina siendo realmente peludo y el desarrollo lleva mucho tiempo. Espero utilizar AngularJS y el enlace de datos para lograr esto en una fracción del código y el tiempo.

Así que aquí está la pregunta: ¿Es posible actualizar la matriz de respaldo de esta manera, pero solo modificar los elementos DOM correspondientes a los elementos / propiedades que realmente cambiaron?


Aquí hay un caso de prueba mínimo que simula un sondeo periódico usando una matriz codificada en un temporizador (véalo en vivo en http://jsfiddle.net/DWrmP/) Tenga en cuenta que la selección de texto se borra cada 500 ms debido a que los elementos se eliminan y vuelven a crear.

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

32
2018-06-13 05:00


origen


Respuestas:


Para aquellos que encuentran esto en Google, la página siguiente describe una característica en AngularJS 1.2 que ayuda con este problema:

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


Editar para agregar: Las oraciones más importantes de la publicación vinculada, en caso de que el enlace muera alguna vez:

Con la nueva sintaxis de "seguimiento por", ahora puedo decirle a AngularJS qué propiedad del objeto (o ruta de propiedad) se debe usar para asociar un objeto JavaScript con un nodo DOM. Esto significa que puedo intercambiar objetos JavaScript sin destruir los nodos DOM siempre y cuando la asociación "track by" siga funcionando.


36
2018-01-15 21:18



Creo que este artículo explicará cómo funciona ngRepeat

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

Entonces, si mantiene los objetos en la colección, entonces sí (i e $ hashKey persiste)

De otra manera no


7
2018-06-13 05:07



Estoy planeando construir la siguiente solución yo mismo eventualmente, aunque todavía está en la cartera de pedidos de mi producto.

El problema con ng-repeat es que eliminará elementos del DOM cuando sea necesario, por lo que para una tabla significaría que cambiará el tamaño y eso, pero si los datos son dinámicos, pueden parpadear porque los datos cambian y el tamaño de la tabla está cambiando Particularmente durante la búsqueda porque toda la página puede no haberse cargado aún.

Para evitar este parpadeo, la tabla no debe cambiar su número de filas. En su lugar, tenga una repetición ng de los datos "mostrados" y simplemente cámbielos según sea necesario sin agregar o eliminar elementos de la matriz.


0
2018-04-17 04:45