AngularJS: Bersihkan $ watch


277

Saya memiliki fungsi arloji dalam aplikasi AngularJS saya.

$scope.$watch('quartzCrystal', function () {
   ...
}

Namun, setelah beberapa kondisi (dalam contoh saya, mengubah halaman pada aplikasi satu halaman saya) saya ingin menghentikan arloji itu (seperti membersihkan timeout).

Bagaimana saya bisa melakukan itu?

Jawaban:


520

$watchmengembalikan fungsi deregistrasi. Menyebutnya akan membatalkan pendaftaran $watcher.

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch

24
Apakah Anda tahu apakah itu praktik yang baik untuk membatalkan pendaftaran semua pendengar Anda di akhir siklus hidup pengontrol (seperti pada a $on('$destroy')) atau AngularJS akan merawat mereka? Terima kasih!
Yorch

81
Semua pengamat akan dihapus ketika ruang lingkup dihancurkan, Anda tidak perlu mengelolanya
Umur Kontacı

6
Anda dapat melihat diskusi menarik di sini yang menjelaskan masalah ini: github.com/angular/angular.js/issues/4574 Pada dasarnya, jika Anda menetapkan pendengar ke $ rootScope, Anda harus membatalkan penetapannya sendiri, atau itu akan bertahan melalui $ lingkup perubahan. Pengamat pada $ scope dihancurkan dengan $ scope ($ scopes bukan singletons di Angular, dan mereka dibuat dan dihancurkan ketika dibutuhkan).
Mladen Danic

3
Tapi, bagaimana jika saya hanya ingin pengamat memeriksa apakah nilainya ada dan kemudian ketika ada lakukan beberapa perubahan dan kemudian de register sendiri saya sudah mencoba - var mendengarkan = $ lingkup. $ Watch ('mvIdentity.currentUser', fungsi (currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); Listen ();});
Harshit Laddha

4
@ UmurKontacı Sebenarnya komentar deadman sangat valid karena komentar asli Anda tidak benar untuk setiap kasus.
GFoley83

49

scope. $ watch mengembalikan fungsi yang dapat Anda panggil dan yang akan membatalkan registrasi arloji.

Sesuatu seperti:

var unbindWatch = $scope.$watch("myvariable", function() {
    //...
});

setTimeout(function() {
    unbindWatch();
}, 1000);

14
Ya, Anda dapat melepaskan ikatan di dalam watchFn! Kasing sederhana: Anda ingin menonton dan menjalankan watchFn hanya sekali, kemudian berhenti menonton.
Mike Rapadas

3
Apakah saya dapat memutar ulang arloji setelah saya memanggil fungsi tidak mengikat, seperti memanggilnya lagi?
Bruno Finger

Ini bermanfaat. Melakukan unbindWatch dalam batas waktu sepertinya penting dalam pengujian saya.
eeejay

Dalam hal ini Anda harus menggunakan $ timeout, yang juga dapat Anda batalkan registrasi!
Ben Taliadoros

Terbaik untuk menghindari batas waktu
Davi Lima

25

Anda juga dapat menghapus arloji di dalam callback jika Anda ingin menghapusnya segera setelah sesuatu terjadi. Dengan begitu $ watch Anda akan tetap aktif sampai digunakan.

Seperti ...

var clearWatch = $scope.$watch('quartzCrystal', function( crystal ){
  if( isQuartz( crystal )){
    // do something special and then stop watching!
    clearWatch();
  }else{
    // maybe do something special but keep watching!
  } 
}

4

Kadang-kadang $ watch Anda menelepon dynamicallydan itu akan membuat contohnya sehingga Anda harus memanggil fungsi deregistrasi sebelum $watchfungsi Anda

if(myWatchFun)
  myWatchFun(); // it will destroy your previous $watch if any exist
myWatchFun = $scope.$watch("abc", function () {});

4

Idealnya, setiap jam tangan khusus harus dihapus ketika Anda meninggalkan ruang lingkup.

Ini membantu dalam manajemen memori yang lebih baik dan kinerja aplikasi yang lebih baik.

// call to $watch will return a de-register function
var listener = $scope.$watch(someVariableToWatch, function(....));

$scope.$on('$destroy', function() {
    listener(); // call the de-register function on scope destroy
});

4

Jika Anda memiliki terlalu banyak pengamat dan Anda harus menghapus semuanya, Anda dapat mendorong mereka ke dalam array dan menghancurkan setiap $watchdalam satu lingkaran.

var watchers = [];
watchers.push( $scope.$watch('watch-xxx', function(newVal){
   //do something
}));    

for(var i = 0; i < watchers.length; ++i){
    if(typeof watchers[i] === 'function'){
        watchers[i]();
    }
}

watchers = [];

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.