2013-07-08 8 views
6

Sto tentando di aggiornare ng-grid con l'array splice. Ho un plunk here.AngularJS/ng-grid - L'aggiornamento dell'array con splice non aggiorna l'interfaccia utente

Il pulsante Aggiungi consente di aggiungere nuove righe. Il pulsante Aggiorna aggiorna l'ultimo elemento nell'array.

  1. Selezionare una riga & premere il pulsante di aggiornamento. Non accade nulla.
  2. Premere il pulsante Aggiungi. Ora l'interfaccia utente viene aggiornata con il nuovo elemento & e l'elemento precedentemente aggiornato.
  3. Lo stesso comportamento viene ripetuto nuovamente &.

Ho provato $scope.$apply. Ottengo:

“Error: $apply already in progress”

Ho anche provato mettendo $scope.$apply blocco all'interno di una chiamata setTimeout. Di nuovo lo stesso errore!

Qualsiasi suggerimento!

Grazie!

risposta

15

Questo perché i dati $ watcher in ng-grid (erroneamente) confronta l'oggetto dei dati di riferimento, anziché sulla parità oggetto. Si potrebbe ovviare a questo impostando il terzo parametro di vero in data $watch function (linea 3128):

$scope.$parent.$watch(options.data, dataWatcher, true); 

Plunker

+0

Ti darei 100 punti se potessi ... questo mi ha ucciso durante l'aggiornamento della mia origine dati remota. – Nicros

+0

Non era ovvio per me dove inserire il codice in questa domanda; quindi volevo solo aggiungere che si trattava di una mod nel file grid.js. – JeffryHouser

+0

Sai se questo è stato risolto nella nuova versione di ng-grid? Penso di avere un problema molto simile. – Naomi

4

UPDATE (2015-04-10)

angolare ha migliorato la loro base di codice (1.4.0), provare prima il metodo $scope.$watchCollection e vedere se funziona per voi. (Link)

RISPOSTA

Se non avete voglia di hacking in una libreria di terze parti, è possibile aggiungere l'hack nel codice utilizzando:

$scope.updateData = function() { 
    var data = angular.copy($scope.myData); 
    data.splice(data.length - 1, 1, {name: 'UPDATED', age: '4'}) 
    $scope.myData = data; 
}; 

plunkr

Come cita @Stewie, il problema è che, per motivi di prestazioni, ngGrid confronta l'oggetto dati in modo superficiale e, nel caso degli array, ciò avviene in base a Renče. ngGrid confronta anche dalla lunghezza della matrice, quindi se la matrice non cambia la sua lunghezza la griglia wont' ottenere aggiornato.

Questa soluzione crea una copia dell'array (diversa posizione in memoria) in modo che quando angularjs $watcher verifica le modifiche, troverà un oggetto diverso ed eseguirà il callback dell'aggiornamento ngGrid.

NOTA: Perché questa soluzione crea una copia della matrice di dati in ciascuna chiamata a updateData, potrebbe portare a problemi di prestazioni se i dati è troppo grande, anche Javascript non ha una grande raccolta dei rifiuti.

Vecchio Risposta non corretta:

$timeout(angular.noop, 0);

Questo imposta semplicemente un timeout per innescare un $scope.$apply() dopo quella corrente è fatto. Un modo per forzare un assegno sporco.

+0

Riesci a ottenere un Plunkr di questo lavoro? Non sta funzionando per me. – Alain

+0

@Alain, hai ragione la risposta '$ timeout' non funziona. Ha funzionato per me, ma perché ero in una situazione diversa. Ho aggiornato la mia risposta con una soluzione valida. – guzart

0

Sto usando ui-grid v3.0.0 (da una build instabile di aprile 2015). Ho trovato questo post e voluto mostrare agli altri come ho rinfrescato la griglia dopo aver rimosso una riga dall'oggetto dati griglia utilizzando splice:

// Remove the row and refresh the grid. 
$scope.myData.splice(rowIndex, 1); 
$scope.gridApi.grid.refresh(true); 

dove la variabile portata gridApi stato impostato con questa funzione:

$scope.gridOptions.onRegisterApi = function(gridApi){ 
    $scope.gridApi = gridApi; 
}