track index example array javascript angularjs ng-repeat angularjs-track-by

javascript - index - ng-repeat group by



¿Qué es "track by" en AngularJS y cómo funciona? (3)

Realmente no entiendo cómo funciona la track by y lo que hace.
Mi objetivo principal es usarlo con ng-repeat para agregar algo de precisión.


Usando track by para rastrear cadenas y valores duplicados

Normalmente ng-repeat rastrea cada elemento por el propio elemento. Para la matriz dada objs = [ ''one'', ''one'', 2, ''five'', ''string'', ''foo''] , ng-repeat intenta hacer un seguimiento de los cambios realizados por cada objeto en ng-repeat="obj in objs" . El problema es que tenemos valores duplicados y angular arrojará un error. Una forma de resolverlo es tener un seguimiento angular de los objetos por otros medios. Para cadenas, track by $index es una buena solución ya que realmente no tiene otros medios para rastrear una cadena.

track by y activando un resumen y los enfoques de entrada

Usted alude al hecho de que es algo nuevo para angular. Un ciclo de digestión se produce cuando angular realiza una comprobación exhaustiva de cada propiedad observada para reflejar cualquier cambio en la vista correspondiente; A menudo, durante un ciclo de resumen, sucede que su código modifica otras propiedades observadas, por lo que el procedimiento debe realizarse nuevamente hasta que el ángulo no detecte más cambios.

Por ejemplo: hace clic en un botón para actualizar un modelo mediante ng-click , luego hace algunas cosas (es decir, las cosas que escribió en la devolución de llamada para realizar cuando un usuario hace clic), y luego el ciclo de resumen del disparador angular para actualizar la vista. No soy muy elocuente para explicar eso, así que deberías investigar más si eso no aclara las cosas.

Así que volvemos a la track by . Vamos a usar un ejemplo:

  1. llamar a un servicio para devolver una matriz de objetos
  2. actualizar un objeto dentro de la matriz y guardar objeto
  3. después de guardar el servicio, dependiendo de lo que devuelva la API, puede:
    1. reemplazar todo el objeto o
    2. actualizar un valor en el objeto existente
  4. reflejar el cambio en la interfaz de usuario de ng-repeat

La forma en que rastree este objeto determinará cómo la interfaz de usuario refleja el cambio.

Una de las UX más molestas que he experimentado es esta. Supongamos que tiene una tabla de objetos, cada celda tiene una entrada donde desea editar en línea las propiedades de esos objetos. Quiero cambiar el valor, luego on-blur , guardar ese objeto mientras me muevo a la siguiente celda para editar mientras podría estar esperando la respuesta. Así que esto es una cosa del tipo de autoguardado. Dependiendo de cómo configure su track by declaración, puede perder el enfoque actual (por ejemplo, el campo que está editando actualmente) cuando la respuesta se vuelve a escribir en su matriz de objetos.


Cuando agrega una track by , básicamente le dice a angular que genere un único elemento DOM por objeto de datos en la colección dada.

Puede track by $index si su fuente de datos tiene identificadores duplicados.

Si necesita repetir elementos duplicados, puede sustituir el comportamiento de seguimiento predeterminado con el suyo utilizando la pista por expresión.

Ejemplo:

[{id:1,name:''one''}, {id:1,name:''one too''}, {id:2,name:''two''}]

Intente usar los valores duplicados en ng-repeat , obtendrá un error como:

Error: ngRepeat: duplica la clave duplicada en el repetidor

Para evitar este tipo de problemas, debe utilizar track by $index . Por ejemplo:

<ul> <li ng-repeat="item in [1, 2, 3, 3] track by $index"> {{ item }} </li> </ul>

Aquí es cómo obtendría $index en ng-repeat anidada:

<div ng-repeat="row in matrix"> <div ng-repeat="column in row"> <span>outer: {{$parent.$index}} inner: {{$index}}</span> </div> </div>

Aquí hay algunos recursos que pueden ayudarte:


Solo debe usar track by si necesita ir en contra del comportamiento predeterminado de ng-repeat que es eliminar elementos duplicados.
Puede hacer un seguimiento de los elementos utilizando la propiedad de alcance $index o especificando una función personalizada.

Por ejemplo:

<div ng-repeat="x in [42, 42, 43, 43] track by $index"> {{x}} </div>

Mostrar todos los valores de la matriz (42 se muestra dos veces).

Para referencia: https://docs.angularjs.org/api/ng/directive/ngRepeat