ng-repeat não atualizando na atualização do array

Estou processando dados por meio de um ciclo de repetição de ng. E eu gostaria que atualize como eu atualizo o array. Pelo que eu li isso deve acontecer automaticamente no entanto isso não está funcionando. Então, o que estou fazendo de errado?

html:

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

Controlador (esta function é acionada em um botão com ng-click):

 $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 a matriz é atualizada corretamente, no entanto, a tabela na minha exibição não é alterada. Eu não sei o que estou fazendo errado.

Isso é porque você altera a referência da matriz em seu método getDifferences .

Para evitar isso, us dot , por exemplo com a syntax “controller as”:

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

Se você quiser entender como funcionam os escopos, aconselho este artigo: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ngRepeat

Outra solução poderia 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 }) } } 

mas nesta solução, você precisa criar o array fora (e somente uma vez): $scope.dataDifferenceArray = [];

Edit2: Minha resposta não foi muito clara, vamos tentar entender o que está acontecendo no fundo:

P: Por que o ng-repeat ainda tem a referência REFERENCE1?

Você precisa lembrar que não há apenas um escopo no seu modelo .

Por exemplo: a diretiva ng-repeat cria novos escopos para cada um dos elementos repetidos, mas ainda podemos acessar o escopo pai em cada escopo filho. Angular implementou esse comportamento usando Herança de Protótipo : cada escopo filho herda as propriedades de seu escopo pai graças ao seu protótipo.

Você pode experimentar como ele está funcionando, inspecionando um em seus elementos filho, em seguida, digite no console: $($0).scope() (ele lhe dará o escopo do elemento selecionado, $0 é o elemento selecionado (Chrome)) . Agora você pode ver que existe o mesmo object em $($0).scope().$parent e $($0).scope().__proto__ , é seu escopo pai.

Mas há um problema com inheritance de protótipo: digamos que temos A = {}; B = {C: 1} A = {}; B = {C: 1} , se A herdar de B então AC == 1 . Mas se nós afetamos um novo valor AC = 2 , nós não mudamos B , apenas A

Expressões angulares são avaliadas usando o escopo atual como this . Então, se temos algo como ng-click="dataDifferenceArray = []" é equivalente a this.dataDifferenceArray = [] sendo this o escopo do elemento onde ng-click é.

Esse problema é resolvido quando você está usando controlador-como porque ele injeta o controlador no escopo e você nunca afetará diretamente uma propriedade para o escopo.

Vamos retomar nosso exemplo: A = {}; B = {C: {D: 1}} A = {}; B = {C: {D: 1}} , se A herdar de B então ACD == 1 . E agora, mesmo se nós afetamos um novo valor ACD = 2 , nós mudamos B também.

mesmo quando atualizando corretamente a referência da matriz, eu estava tendo o mesmo problema, ng-repeat não estava processando minhas alterações. Finalmente encontrei a solução chamando $ 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 isso possa ajudar.

Eu não fiz nada, mas adicionei esta linha ” $ scope. $ Apply () ” depois de empurrar o elemento, e eu terminei.

Para aqueles que têm uma matriz sendo definida dentro do escopo (ou seja, $scope.$apply() causa um erro se chamado depois de um push), mas ainda não está atualizando corretamente no DOM, minha solução foi chamar essa function imediatamente após a atualização push / slice / array:

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

Passando em container e key , onde container neste caso seria $scope e key seria "dataDifferenceArray" (observe as aspas).

Não tenho ideia do motivo pelo qual o DOM não é atualizado corretamente em alguns casos. Ele mostra o número correto de elementos, e é atualizado quando um novo elemento é adicionado, ele simplesmente não atualiza os elementos filho DOM corretamente (ou seja, o elemento recém-lançado pode assumir a visão DOM do filho anterior). Isto pode ser devido a como nós redefinimos this para vm no Angular Style Guide de Johnpapa , mas eu não estou confiante nisso.

Na verdade, parece que sua matriz está sendo definida para vazia dentro da function de clique. Isso funcionará se você mover o escopo de seus arrays para fora da function.

Exemplo

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