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?

kamaci
sumber

Jawaban:

520

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

var listener = $scope.$watch("quartz", function () {});
// ...
listener(); // Would clear the watch
Umur Kontacı
sumber
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);
Anders Ekdahl
sumber
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!
  } 
}
SoEzPz
sumber
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 () {});
naCheex
sumber
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
});
Manish Kumar
sumber
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 = [];
Rewar
sumber
-10

Untuk membuang salinan pengamat, Anda dapat menggunakan ini:

watchers = void 0;
shailendra pathak
sumber