2013-03-15 11 views
96

Supponiamo di voler eseguire qualcosa come eseguire automaticamente del codice (come il salvataggio dei dati su un server) ogni volta che i valori di un modello cambiano. È l'unico modo per farlo impostando qualcosa come ng-change su ogni controllo che potrebbe alterare il modello?AngularJS: rileva automaticamente la modifica nel modello

Cioè, con le viste, le cose cambiano quando il modello viene cambiato senza dover agganciare esplicitamente qualcosa. Esiste un analogo per poter eseguire il codice che salva su un server? Qualcosa come

myModel.on('change', function() { 
    $.post("/my-url", ...); 
}); 

come si potrebbe vedere con qualcosa come backbone.

risposta

142

Nelle viste con {{}} e/o modello ng, Angular sta configurando $watch() per voi dietro le quinte.

Per impostazione predefinita, $watch confronta per riferimento. Se si imposta il terzo parametro su $watch su true, Angular invece "shallow" guarda l'oggetto per le modifiche. Per gli array questo significa confrontare gli elementi dell'array, per le mappe degli oggetti questo significa guardare le proprietà. Quindi questo dovrebbe fare quello che vuoi:

$scope.$watch('myModel', function() { ... }, true); 

Aggiornamento: v1.2 angolare aggiunto un nuovo metodo per questo, `$watchCollection():

$scope.$watchCollection('myModel', function() { ... }); 

notare che la parola "superficiale" è usato per descrivere il confronto piuttosto che "profondo" perché i riferimenti non vengono seguiti - ad esempio, se l'oggetto guardato contiene un valore di proprietà che è un riferimento a un altro oggetto, tale riferimento non viene seguito per confrontare l'altro oggetto.

+1

Ah, fantastico! C'è qualche ragione per cui questo non sembra essere tutto ciò che è documentato (cioè, non penso che nessuno dei tutorial sul sito angolare menziona l'impostazione di $ orologi direttamente)? C'è qualcosa di negativo in questo aspetto che renderebbe l'idea di impostare (potenzialmente più) ganci "ng-change" su input per una migliore idea? – Alec

+12

Sì, sarebbe bello se il tutorial principale menzionasse $ guardare da qualche parte.Ciò che è "cattivo" in questo approccio è che può richiedere molto tempo se il tuo modello è di grandi dimensioni (ogni ciclo di digestione - ogni sequenza di tasti in un campo di input) risulterà in questo modello sottoposto a controllo approfondito, forse più volte) . In tal caso, selettivi $ watch() o ng-change selettivi sarebbero migliori. –

7

E se è necessario per lo stile i vostri elementi del modulo in base al suo stato (modificato/non modificati) in modo dinamico o per verificare se alcuni valori è effettivamente cambiato, è possibile utilizzare il seguente modulo, sviluppato da me: https://github.com/betsol/angular-input-modified

Aggiunge ulteriori proprietà e metodi al modulo ed è elementi figlio. Con esso, puoi verificare se alcuni elementi contengono nuovi dati o anche testare se l'intero modulo ha nuovi dati non salvati.

È possibile impostare il seguente orologio: $scope.$watch('myForm.modified', handler) e il gestore verrà chiamato se alcuni elementi del modulo contengono effettivamente nuovi dati o se sono stati invertiti allo stato iniziale.

Inoltre, è possibile utilizzare la proprietà modified dei singoli elementi del modulo per ridurre effettivamente la quantità di dati inviati a un server tramite chiamata AJAX. Non è necessario inviare dati invariati.

Come bonus, è possibile ripristinare il modulo allo stato iniziale tramite la chiamata al metodo reset() del modulo.

Potete trovare demo del modulo qui: http://plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

Cheers!

+0

C'è un modo per controllare questo nel controller. per esempio se il clic sul pulsante x può fare come un if (myform.modified) mostra popup di conferma? – Flash

+0

Ovviamente basta passare FormController alla funzione del controller: '

', '
+0

grazie questo farà qualcosa solo se il modulo è stato modificato giusto? – Flash

Problemi correlati