AngularJS: ล้าง $ watch


277

ฉันมีฟังก์ชั่นนาฬิกาในแอปพลิเคชัน AngularJS ของฉัน

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

อย่างไรก็ตามหลังจากเงื่อนไขบางอย่าง (ในตัวอย่างของฉันการเปลี่ยนหน้าในแอปพลิเคชันหน้าเดียวของฉัน) ฉันต้องการหยุดการเฝ้าดูนั้น (เช่นการล้างการหมดเวลา)

ฉันจะทำสิ่งนั้นได้อย่างไร

คำตอบ:


520

$watchส่งคืนฟังก์ชันการลงทะเบียน เรียกมันว่าจะยกเลิกการลงทะเบียน$watcher

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

24
คุณรู้หรือไม่ว่าเป็นการดีที่จะลงทะเบียนผู้ฟังทั้งหมดของคุณในตอนท้ายของวงจรชีวิตตัวควบคุม (เช่นบน$on('$destroy')) หรือ AngularJS จะดูแลพวกเขา? ขอบคุณ!
yorch

81
นักดูทั้งหมดจะถูกลบออกเมื่อขอบเขตถูกทำลายคุณไม่จำเป็นต้องจัดการสิ่งเหล่านั้น
Umur Kontacı

6
คุณสามารถดูการสนทนาที่น่าสนใจได้ที่นี่ซึ่งอธิบายเรื่องนี้: github.com/angular/angular.js/issues/4574โดยทั่วไปหากคุณกำหนดผู้ฟังให้กับ $ rootScope คุณต้องยกเลิกการมอบหมายด้วยตนเองหรือจะยืนยันผ่าน การเปลี่ยนแปลงขอบเขต $ ผู้ดูในขอบเขต $ จะถูกทำลายด้วย $ scope ($ ขอบเขตไม่ใช่ singletons ใน Angular และพวกเขาจะถูกสร้างและทำลายเมื่อจำเป็น)
Mladen Danic

3
แต่จะเกิดอะไรขึ้นถ้าฉันเพียงต้องการให้ผู้เฝ้าดูตรวจสอบว่ามีค่าอยู่หรือไม่และเมื่อมันมีการเปลี่ยนแปลงบางอย่างแล้วจึงทำการลงทะเบียนตัวเองฉันได้ลองแล้ว - var Listen = $ scope $ เฝ้าดู ('mvIdentity.currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); Listen ();});
Harshit Laddha

4
@ UmurKontacıความคิดเห็นของคนตายจริง ๆ แล้วใช้ได้อย่างสมบูรณ์แบบเนื่องจากความคิดเห็นดั้งเดิมของคุณไม่ถูกต้องสำหรับทุกกรณี
GFoley83

49

scope. $ watch ส่งคืนฟังก์ชั่นที่คุณสามารถโทรได้และจะยกเลิกการลงทะเบียนนาฬิกา

สิ่งที่ต้องการ:

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

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

14
ใช่คุณสามารถยกเลิกการผูกไว้ใน watchFn ได้! กรณีใช้งานง่าย: คุณต้องการดูและดำเนินการ watchFn เพียงครั้งเดียวจากนั้นหยุดดู
Mike Rapadas

3
ฉันสามารถ rebind นาฬิกาหลังจากที่ฉันเรียกใช้ฟังก์ชัน unbind ได้หรือไม่เช่นการเรียกอีกครั้ง?
Bruno Finger

สิ่งนี้มีประโยชน์ การทำ unbindWatch ในการหมดเวลาดูเหมือนว่าสำคัญในการทดสอบของฉัน
eeejay

ในกรณีนี้คุณควรใช้ $ timeout ซึ่งคุณสามารถยกเลิกการลงทะเบียนได้!
Ben Taliadoros

ที่ดีที่สุดที่จะหลีกเลี่ยงการหมดเวลา
Davi Lima

25

คุณสามารถล้างนาฬิกาภายในการโทรกลับหากคุณต้องการล้างมันทันทีหลังจากมีบางสิ่งเกิดขึ้น ด้วยวิธีนี้การเฝ้าดู $ ของคุณจะยังคงใช้งานได้จนกว่าจะใช้งาน

ชอบมาก ...

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

บางครั้งนาฬิกา $ ของคุณกำลังโทรdynamicallyและมันจะสร้างอินสแตนซ์ของมันขึ้นมาดังนั้นคุณต้องเรียกใช้ฟังก์ชั่นการยกเลิกการลงทะเบียนก่อน$watchฟังก์ชั่นของคุณ

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

4

ตามหลักการแล้วนาฬิกาที่กำหนดเองทุกรายการควรถูกลบออกเมื่อคุณออกจากขอบเขต

ช่วยในการจัดการหน่วยความจำที่ดีขึ้นและประสิทธิภาพแอปที่ดีขึ้น

// 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

หากคุณมีผู้เฝ้าดูมากเกินไปและคุณต้องกำจัดพวกมันทั้งหมดออกไปคุณสามารถผลักมันเข้าไปในอาเรย์และทำลายทุก ๆ$watchวง

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 = [];

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.