ng-repeat no se actualiza en la actualización de la matriz

Estoy procesando datos a través de un ciclo ng-repeat. Y me gustaría que se actualice a medida que actualice la matriz. Por lo que he leído esto debería suceder automáticamente, pero esto no está funcionando. Entonces, ¿qué estoy haciendo mal?

html:

  {{data.name}}   {{data.startData}}   {{data.endData}}   {{data.differenceData}}   

Controlador (esta función se activa en un botón con ng-clic):

 $scope.getDifferences = function () { $scope.dataDifferenceArray = []; var i; for (i = 0; i < 20 ;i++) { $scope.dataDifferenceArray.push({ name : 30, startData : 20, endData : 2, differenceData : 30 }) } } 

Console.log revela que la matriz se actualiza correctamente, sin embargo, la tabla en mi opinión no cambia. No sé lo que estoy haciendo mal.

Eso es porque cambias la referencia de matriz en tu método getDifferences .

Para evitar eso, use dot , por ejemplo, con la syntax “controller as”:

 
[...] {{data.name}} {{data.startData}} {{data.endData}} {{data.differenceData}} [...]

Si quiere entender cómo funcionan los ámbitos, le aconsejaría este artículo: https://github.com/angular/angular.js/wiki/ Understanding-Scopes# ngRepeat

Otra solución podría ser:

 $scope.getDifferences = function () { $scope.dataDifferenceArray.length = 0; // here ---- var i; for (i = 0; i < 20 ;i++) { $scope.dataDifferenceArray.push({ name : 30, startData : 20, endData : 2, differenceData : 30 }) } } 

pero en esta solución, necesita crear la matriz fuera (y solo una vez): $scope.dataDifferenceArray = [];

Edit2: Mi respuesta no fue muy clara, intentemos comprender lo que está sucediendo en profundidad:

P: ¿Por qué ng-repeat todavía tiene la referencia REFERENCE1?

Debe recordar que no solo hay 1 scope en su plantilla .

Por ejemplo: la directiva ng-repeat crea nuevos ámbitos para cada uno de los elementos repetidos, pero aún podemos acceder al ámbito principal en cada ámbito hijo. Angular implementó este comportamiento utilizando la herencia de prototipos : cada ámbito hijo hereda las propiedades de su ámbito principal gracias a su prototipo.

Puedes experimentar cómo funciona inspeccionando uno de tus elementos secundarios, luego ingresa en la consola: $($0).scope() (te dará el scope del elemento seleccionado, $0 es el elemento seleccionado (Chrome)) . Ahora puede ver que hay el mismo objeto en $($0).scope().$parent y $($0).scope().__proto__ , es su scope principal.

Pero hay un problema con la herencia del prototipo: digamos que tenemos A = {}; B = {C: 1} A = {}; B = {C: 1} , si A hereda de B entonces AC == 1 . Pero si afectamos un nuevo valor AC = 2 , no cambiamos B , solo A

Las expresiones angulares se evalúan usando el scope actual como this . Entonces, si tenemos algo como ng-click="dataDifferenceArray = []" es equivalente a this.dataDifferenceArray = [] siendo this el scope del elemento donde ng-click .

Este problema se resuelve cuando usa el controlador, ya que inyecta el controlador en el scope y nunca afectará directamente una propiedad del scope.

Retomemos nuestro ejemplo: A = {}; B = {C: {D: 1}} A = {}; B = {C: {D: 1}} , si A hereda de B entonces ACD == 1 . Y ahora, incluso si afectamos un nuevo valor ACD = 2 , también cambiamos B

incluso cuando actualicé correctamente la referencia de matriz, estaba teniendo el mismo problema, ng-repeat no representaba mis cambios. Finalmente encontré la solución llamando a $ scope. $ Apply ();

 $window.wizard.on("readySubmit", function () { var newArray = GenesisFactory.GetPermissionsFromTemplate(GenesisFactory.SecurityModules, true); $scope.NewSecurityProfileInstance.Permission.length = 0; newArray.forEach(function (entry) { $scope.NewSecurityProfileInstance.Permission.push(entry); }); $scope.$apply(); }); 

Espero que esto pueda ayudar.

No he hecho nada más que agregar esta línea ” $ scope. $ Apply () ” después de presionar el elemento, y he terminado.

Para aquellos que tienen una matriz establecida dentro del scope (es decir, $scope.$apply() provoca un error si se llama después de un push), pero todavía no se actualiza correctamente en el DOM, mi solución ha sido llamar a esta función inmediatamente después la actualización push / slice / array:

 function applyArray(container, key) { setTimeout(function() { var tempArray = container[key]; container[key] = []; $scope.$apply(); container[key] = tempArray; $scope.$apply(); }, 0); } 

Al pasar el container y la key , donde el container en este caso sería $scope y la key sería "dataDifferenceArray" ( "dataDifferenceArray" las comillas).

No tengo idea de por qué DOM no se actualiza correctamente en algunos casos. Muestra la cantidad correcta de elementos, y se actualiza cuando se agrega un nuevo elemento, simplemente no actualiza los elementos secundarios DOM correctamente (es decir, el elemento recién empujado puede tomar la vista DOM del elemento secundario anterior). Esto podría deberse a cómo redefinimos this a vm en la Guía de estilo angular de Johnpapa , pero no estoy seguro de eso.

En realidad, parece que su matriz se está configurando para vaciarse dentro de la función de clic. Esto funcionará si mueve el scope de sus arreglos fuera de la función.

Ejemplo

 // Declared outside $scope.dataDifferenceArray = []; // Your function $scope.getDifferences = function () { var i; for (i = 0; i < 20 ;i++) { $scope.dataDifferenceArray.push({ name : 30, startData : 20, endData : 2, differenceData : 30 }); } };