AngularJS: ng-repeat con list dinámica, sin rebuild todo el tree DOM?

Estoy usando ng-repeat en una fila de la tabla con datos de una matriz JSON recuperada de un server. Mi objective es que la list se actualice automáticamente cada vez que se agregue, elimine o modifique un elemento en el server, sin afectar los elementos no modificados. En la implementación final, estas filas de la tabla también contendrán elementos <input> y <select> vinculados bidireccionalmente para enviar actualizaciones al server. Algunas de las opciones disponibles en los elementos <select> también se generarán usando las directivas ng-repeat de otra list que también pueden cambiar.

Hasta ahora, cada vez que una nueva matriz proviene del server (actualmente sondeada cada dos segundos), toda la list ng-repeat se borra y se regenera. Esto es problemático porque interfiere con la selección de text, destruye los campos de input 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 time. Espero utilizar AngularJS y el data binding para lograr esto en una fracción del código y el time.

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 / properties que realmente cambiaron?


Aquí hay un caso de testing mínima que simula un sondeo periódico usando una matriz codificada en un timer ( véalo en vivo en http://jsfiddle.net/DWrmP/ ). Tenga en count que la selección de text 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); } ] ); 

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 syntax de "seguimiento por", ahora puedo decirle a AngularJS qué propiedad del object (o ruta de propiedad) se debe usar para asociar un object JavaScript con un nodo DOM. Esto significa que puedo intercambiar objects JavaScript sin destruir los nodos DOM siempre y cuando la asociación "track by" siga funcionando.

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 objects en la colección, entonces sí (es decir, $ hashKey persiste)

De otra manera no

Estoy planeando build 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 dynamics, 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.