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.