5

Ho un elenco di prodotti alimentari in $scope.raw e voglio mostrare questi dati in colonne, quindi sto cambiando leggermente la struttura. Lo faccio nella funzione sortStuff() e memorizzo i dati aggiornati in $scope.allfood. C'è un $ orologio che chiama sortStuff() qualcosa cambia ogni volta che in $scope.raw (sto usando il drag and drop per cambiare la categoria di alimenti):

$scope.$watch('raw', function(){ 
    $scope.allfood = $scope.sortStuff(); 
    console.log($scope.allfood); 
}, true); 

Questo è ciò che accade quando il cibo viene trascinato in giro:

receive:function(event, ui) { 
    var issueScope = angular.element(ui.item).scope(); 
    scope.$apply(function() { 
     var recp = _.find(scope.raw, function(lineitem){ 
      return lineitem.name === issueScope.receipe.name; 
     }) 
     recp.cat = scope.col.name; 
    }) 

    $(ui.item).remove(); // remove DOM 
} 

Fondamentalmente, cerco l'oggetto giusto all'interno di $scope.raw e cambio cat in una nuova categoria per il cibo. Inoltre cancello l'elemento dom perché conto su ng-repeat per aggiornare la vista. Questo sembra funzionare bene: console.log all'interno di $ watch mostra che l'oggetto viene spostato nella giusta categoria e i dati sembrano come dovrebbero apparire. Tuttavia, visivamente, ng-repeat non riflette i dati.

Here's the jsfiddle.

Il trascinamento di un elemento da B a C funziona correttamente. Trascinandone uno da A a B, scompaiono due elementi da B ... i risultati sono molto incoerenti e non ho idea di cosa stia succedendo.

Qualche idea cosa non va? O forse qualche suggerimento per un modo migliore per farlo?

+0

Si deve usare $ watchCollection (funzione 'grezzo',() {}); ma l'ho fatto e vedo ancora gli stessi problemi nella mia app ... – philwills

risposta

5

Il problema con il codice è che la direttiva ng-repeat aggiunge la proprietà $$hashKey a ogni elemento nell'elenco. Questa proprietà viene utilizzata dalla direttiva per associare elementi DOM ad elementi array.

Poiché si passano gli elementi per riferimento, la direttiva ng-repeat scrive la proprietà $$hashKey direttamente negli oggetti dell'array $scope.raw. Una semplice soluzione è copiare gli oggetti prima di inserirli nell'oggetto $scope.allfood.

_.each($scope.raw, function(recp){ 
    recp = _.clone(recp); 
    switch(recp.cat){ 
     ... 
    } 
}); 

Ora la ng-repeat aggiorna gli oggetti di $scope.allfood, mentre gli oggetti di $scope.raw restano invariati.

Vedere il violino aggiornamento:

http://jsfiddle.net/b8Fa7/5/

+0

Grazie, funziona! Due domande: è possibile clonare un oggetto senza proprietà come '$$ hashKey' che sono state aggiunte da angolare? Inoltre, pensi che ci sia un modo migliore per farlo? Il fatto che l'angolare rigenera l'intero '$ scope.allfood' su ogni cambiamento non può essere buono per le prestazioni e mi piacerebbe evitarlo in qualche modo. – networkprofile

+1

'angular.copy' fornisce un modo per creare una copia profonda di un array o di un oggetto senza proprietà come' $$ hashKey': http://docs.angularjs.org/api/angular.copy – frececroka

+1

Probabilmente potresti tenere traccia di tutte le modifiche all'array '$ scope.raw' e modifica l'oggetto' $ scope.allfood' in base alle modifiche tracciate. Non penso che questo porti ad un notevole miglioramento delle prestazioni purché la lista sia piccola. – frececroka

Problemi correlati