ng-change dapatkan nilai baru dan nilai asli

118

Saya menggunakan ng-options untuk memilih nilai dari pull-down. Saya ingin bisa membandingkan nilai lama dengan nilai baru. ng-change berfungsi dengan baik untuk mengambil nilai baru pull down, tetapi bagaimana saya bisa mendapatkan nilai baru dan nilai aslinya?

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

Misalnya, saya ingin pengontrol mencatat, "Nama pengguna.anda sebelumnya adalah BILL, nama pengguna Anda saat ini adalah PHILLIPE."

Bailey Smith
sumber
1
periksa jawaban saya di sini stackoverflow.com/questions/21909163/… mungkin duplikat
bresleveloper
tidak yakin bagaimana ini bekerja secara administratif tetapi entah bagaimana jawaban dari duplikat harus digabungkan dengan yang ini. bresleveloper adalah solusi yang bagus (dari duplikat) tetapi jawaban TGH harus ditampilkan juga. Yang pertama mengandalkan cara kerja framework, yang bisa berubah di masa depan, sedangkan yang kedua adalah framework agnostik.
pengguna1821052

Jawaban:

279

Dengan sudut {{ekspresi}} Anda bisa menambahkan nilai pengguna lama atau user.id ke atribut ng-change sebagai string literal:

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

Di ngChange, argumen pertama ke updateValue akan menjadi nilai pengguna baru, argumen kedua akan menjadi literal yang terbentuk saat tag-pilih terakhir diperbarui oleh sudut, dengan nilai user.id yang lama.

db-inf
sumber
6
Perhatikan bahwa userpemanggilan metode in adalah dari ng-model, dan bukan dari ng-options (mungkin menyesatkan). Semoga solusi elegan ini akan bekerja juga di versi angular yang akan datang :)
icl7126
15
Ini harus dianggap berbahaya. Saya baru saja menemukan bug kotor yang terjadi ketika user.id berisi karakter khusus (seperti 'atau /). Ini karena parser ekspresi Angular tidak menyukai ekspresi seperti updateValue (pengguna,' bla / bla ').
Antoine Banctel-Chevrel
2
Di fungsi updateValue, $ scope.user.id sudah berisi nilai yang baru dipilih - tidak perlu meneruskan parameter untuk nilai baru itu
Majix
@ LINQ2Vodka, saya pikir ini hanya berfungsi tanpa tanda kutip jika user.idnumerik ... tidak akan berfungsi jika user.idberupa string atau guid
Tamas
1
indah :))))
Makatun
16

Anda juga bisa menggunakan

<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>
Umut Catal
sumber
1
Jawaban ini bekerja sangat baik dalam ng-repeat. Anda juga bisa menggunakan ng-click jika elemen yang Anda gunakan mendukung ng-change tapi tidak ng-focus.
meticoeus
1
ng-init = "oldValue = 0" & ng-focus = "oldValue = user.id" berhasil untuk saya.
thatzprem
14

Anda bisa menggunakan sesuatu seperti ng-change = someMethod ({{user.id}}). Dengan mempertahankan nilai Anda di sisi {{ekspresi}}, ini akan mengevaluasi ekspresi sebaris dan memberi Anda nilai saat ini (nilai sebelum metode ng-change dipanggil).

<select ng-model="selectedValue" ng-change="change(selectedValue, '{{selectedValue}}')">
Vivek Panday
sumber
13

Cukup pertahankan variabel currentValue di pengontrol yang Anda perbarui pada setiap perubahan. Anda kemudian dapat membandingkannya dengan nilai baru setiap kali sebelum Anda memperbaruinya. '

Ide untuk menggunakan jam tangan juga bagus, tetapi menurut saya variabel sederhana adalah solusi paling sederhana dan paling logis.

TGH
sumber
Jam tangan adalah operasi yang sedikit mahal, saya menyukai jawaban db-inf .. ini adalah solusi kerja yang sederhana
Pramod Sharma
4
Jawaban Terbaik. Jika Anda berada di dalam ng-repeat, buat variabel dalam sub-cakupan menggunakan ng-init.
Romain F.
1
IMHO ini adalah alternatif terbaik. Karena mengambil nilai lama tidak disediakan oleh ngChange out-of-the-box, solusi seperti yang dari @ db-inf mungkin meledak pada versi mendatang. Selain itu, ini terdengar seperti tanggung jawab pengontrol, sepertinya aneh untuk mendelegasikannya ke lapisan tampilan.
Felipe Leão
9

Anda dapat menggunakan arloji lingkup:

$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

tommybananas
sumber
6
Saya telah menemukan sebuah artikel yang menyatakan bahwa arloji jauh lebih kotor / tidak efisien dibandingkan dengan ng-change. benlesh.com/2013/10/title.html
Menios
5
Menurut pengalaman saya, Anda hampir tidak pernah ingin menggunakan jam tangan
nardnob
2
Jika pemrograman adalah seni subjektif, Anda mungkin memiliki sesuatu di sana. Sayangnya - ada banyak alasan mengapa Anda mungkin ingin menghindari ng-charge atau pendekatan berbasis direktif lainnya, yang tidak terkait dengan melakukan sesuatu dengan cara "bersudut".
tommybananas
2

Anda dapat menggunakan arloji sebagai gantinya, karena itu memiliki nilai lama dan baru, tetapi kemudian Anda menambah siklus intisari.

Saya hanya akan menyimpan variabel kedua di controller dan mengaturnya.

pengguna12121234
sumber
Ini adalah contoh yang cukup sepele, saya lebih memilih keterbacaan daripada mengkhawatirkan satu pengamat dalam hal ini. Masih bagus untuk menjadi lelah kurasa.
tommybananas
1
Watch dan ng-change sebenarnya memiliki perilaku yang berbeda: ng-change hanya mendeteksi kejadian pengguna, sedangkan $watchakan diaktifkan setiap kali variabel berubah. Pengamat meningkatkan kompleksitas dan cenderung membuat siklus pembaruan ketika kode mengubah nilainya.
Rhys van der Waerden
Saya setuju dengan @Rhys van der Waerden ... artikel ini menyatakan bahwa $ watch agak berbahaya: benlesh.com/2013/10/title.html
Menios