2014-10-29 20 views
89

Sto usando le opzioni -g per selezionare i valori da un pulldown. Mi piacerebbe essere in grado di confrontare il vecchio valore con il nuovo valore. ng-change funziona bene per afferrare il nuovo valore del pull down, ma come posso ottenere sia il nuovo valore sia il valore originale?ng-change ottiene il nuovo valore e il valore originale

<select ng-change="updateValue(user)" ng-model="user.id" ng-options="user.id as user.name for user in users"></select> 

Per esempio, diciamo che ho voluto il controller per registrare, "Il tuo ex user.name stato Bill, il nome utente corrente è PHILLIPE."

+1

leggi la mia risposta qui http://stackoverflow.com/questions/21909163/get-old-value-and-new-value-from-dropdown/28296355 # 28296355 potrebbe essere duplicato – bresleveloper

+0

non so come funziona amministrativamente ma in qualche modo le risposte dal duplicato devono essere unite con questo. bresleveloper è una buona soluzione (dal duplicato) ma dovrebbe essere mostrata anche la risposta del TGH. Il primo si basa sul funzionamento del framework, che potrebbe cambiare in futuro, mentre il secondo è agnostico del framework. – user1821052

risposta

236

Con un angolare {{espressione}} è possibile aggiungere l'utente vecchio o il valore user.id all'attributo ng-cambiamento come una stringa letterale:

<select ng-change="updateValue(user, '{{user.id}}')" 
     ng-model="user.id" ng-options="user.id as user.name for user in users"> 
</select> 

Sul ngChange, il primo argomento di UpdateValue volontà essere il nuovo valore utente, il secondo argomento sarà il letterale che si è formato quando il tag select è stato aggiornato per ultimo da angolare, con il vecchio valore user.id.

+5

Nota che l'utente 'in method call è quello di 'ng-model', e non di ng-options (potrebbe essere fuorviante). Speriamo che questa soluzione elegante funzioni anche nelle future versioni di angolari :) – icl7126

+11

Questo dovrebbe essere considerato dannoso. Ho appena trovato un bug sporco che si verifica quando user.id contiene un carattere speciale (come 'o /). Questo perché il parser di espressioni angolari non ama espressioni come updateValue (utente,' blah/blah '). –

+1

Nella funzione updateValue, $ scope.user.id contiene già il valore appena selezionato - non è necessario passare un parametro per il nuovo valore ad esso – Majix

11

Basta mantenere una variabile di valore corrente nel controller che si aggiorna ad ogni modifica. Puoi quindi confrontarlo con il nuovo valore ogni volta che lo aggiorni. '

L'idea di utilizzare un orologio è buona, ma penso che una variabile semplice sia la soluzione più semplice e logica.

+0

L'orologio è un'operazione poco costosa, mi è piaciuta la risposta di db-inf .. è la soluzione di lavoro semplice –

+3

La migliore risposta. Se ci si trova all'interno di una ripetizione ng, creare una variabile nel sotto-ambito usando ng-init. –

+0

IMHO questa è la migliore alternativa. Poiché il recupero di vecchi valori non è fornito da ngChange out-of-the-box, soluzioni come quella di @ db-inf potrebbero implodere su versioni future. Inoltre, questo suona come la responsabilità di un controller, sembra strano delegarlo al livello di vista. –

8

È possibile utilizzare un orologio ambito:

$scope.$watch('user', function(newValue, oldValue) { 
    // access new and old value here 
    console.log("Your former user.name was "+oldValue.name+", you're current user name is "+newValue.name+"."); 
}); 

https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

+6

Mi sono imbattuto in un articolo in cui si afferma che l'orologio è molto più sporco/inefficiente rispetto a ng-change. http://www.benlesh.com/2013/10/title.html –

+4

Nella mia esperienza quasi mai si desidera utilizzare un orologio – nardnob

+1

Se la programmazione era un'arte soggettiva si potrebbe avere qualcosa lì.Ahimè - ci sono molte ragioni per cui si potrebbe voler evitare l'uso di ng-charge o altri approcci basati su direttive, non correlate a fare le cose in modo "angolare". – tommybananas

2

Si potrebbe usare un orologio, invece, a causa che ha il vecchio e il nuovo valore, ma poi si aggiunge al ciclo digest.

Vorrei solo mantenere una seconda variabile nel controller e impostarla.

+0

Questo è un esempio abbastanza banale, mi piacerebbe prendere una maggiore leggibilità rispetto a un singolo osservatore in questa istanza. Ancora una buona cosa per essere stanco di suppongo. – tommybananas

+1

L'orologio e la modifica hanno in realtà comportamenti diversi: ng-change rileva solo gli eventi utente, mentre '$ watch' si attiva ogni volta che cambia la variabile. Gli osservatori aumentano la complessità e sono inclini a creare cicli di aggiornamento quando il codice cambia i loro valori. –

+0

Sono d'accordo con @Rhys van der Waerden ... questo articolo afferma che $ watch è un po 'pericoloso: http://www.benlesh.com/2013/10/title.html –

7

È possibile utilizzare qualcosa come ng-change = someMethod ({{user.id}}). Mantenendo il valore in {{espressione}} valuterà l'espressione in-line e fornirà il valore corrente (valore prima che venga chiamato il metodo ng-change).

<select ng-model="selectedValue" ng-change="change(selectedValue, '{{selectedValue}}')"> 
8

Inoltre è possibile utilizzare

<select ng-change="updateValue(user, oldValue)"  
     ng-init="oldValue=0" 
     ng-focus="oldValue=user.id" 
     ng-model="user.id" ng-options="user.id as user.name for user in users"> 
</select> 
+1

Questa risposta funziona molto bene con ng-repeat. Puoi anche usare ng-clic se l'elemento che stai usando su supporta ng-change ma non ng-focus. – meticoeus

+0

ng-init = "oldValue = 0" & ng-focus = "oldValue = user.id" ha fatto il trucco per me. – thatzprem

Problemi correlati