AngularJS: Xóa đồng hồ $


277

Tôi có một chức năng đồng hồ trong ứng dụng AngularJS của tôi.

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

Tuy nhiên, sau một số điều kiện (trong ví dụ của tôi, thay đổi trang trong ứng dụng một trang của tôi) tôi muốn dừng đồng hồ đó (như xóa hết thời gian chờ).

Làm thế nào tôi có thể làm điều đó?

Câu trả lời:


520

$watchtrả về một chức năng hủy đăng ký. Gọi nó sẽ hủy đăng ký $watcher.

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

24
Bạn có biết rằng đó là một cách thực hành tốt để hủy đăng ký tất cả người nghe của bạn ở cuối vòng đời của bộ điều khiển (như trên a $on('$destroy')) hoặc AngularJS sẽ chăm sóc họ không? cảm ơn!
yorch

81
Tất cả người theo dõi sẽ bị xóa khi phạm vi bị phá hủy, bạn không cần phải quản lý những người đó
Umur Kontacı

6
Bạn có thể thấy một cuộc thảo luận thú vị ở đây giải thích vấn đề: github.com/angular/angular.js/issues/4574 Về cơ bản, nếu bạn chỉ định người nghe cho $ rootScope, bạn phải tự hủy bỏ nó, hoặc nó sẽ tiếp tục $ thay đổi phạm vi. Những người theo dõi trên $ scope bị phá hủy với phạm vi $ (phạm vi $ không phải là singletons trong Angular, và chúng được tạo và hủy khi cần).
Mladen Danic

3
Nhưng, điều gì sẽ xảy ra nếu tôi chỉ muốn người theo dõi kiểm tra xem giá trị có tồn tại hay không và khi nó tồn tại, hãy thực hiện một số thay đổi và sau đó tự đăng ký tôi đã thử - var lắng = $ scope. $ Watch ('mvIdentity.cienUser', function (currentUser ) {test = 1; console.log ("->" + $ scope.updateemail + "-" + test); lắng nghe ();});
Harshit Laddha

4
@ UmurKontacı Thực tế bình luận của người chết là hoàn toàn hợp lệ vì nhận xét ban đầu của bạn không đúng cho mọi trường hợp.
GFoley83

49

scope. $ watch trả về một chức năng mà bạn có thể gọi và điều đó sẽ hủy đăng ký đồng hồ.

Cái gì đó như:

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

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

14
Có, bạn có thể hủy liên kết trong watchFn! Trường hợp sử dụng đơn giản: bạn muốn xem và thực hiện watchFn chỉ một lần, sau đó dừng xem.
Mike Rapadas

3
Tôi có thể bật lại đồng hồ sau khi tôi gọi chức năng hủy liên kết, như gọi lại không?
Bruno Finger

Điều này rất hữu ích. Thực hiện unbindWatch trong thời gian chờ có vẻ quan trọng trong thử nghiệm của tôi.
eeejay

Trong trường hợp này, bạn nên sử dụng $ timeout, bạn cũng có thể hủy đăng ký!
Ben Taliadoros

Tốt nhất để tránh thời gian chờ
Davi Lima

25

Bạn cũng có thể xóa đồng hồ bên trong cuộc gọi lại nếu bạn muốn xóa nó ngay sau khi có điều gì đó xảy ra. Bằng cách đó, đồng hồ $ của bạn sẽ duy trì hoạt động cho đến khi được sử dụng.

Giống như vậy ...

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

Đôi khi đồng hồ $ của bạn đang gọi dynamicallyvà nó sẽ tạo các phiên bản của nó để bạn phải gọi chức năng hủy đăng ký trước $watchchức năng của mình

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

4

Lý tưởng nhất, mọi đồng hồ tùy chỉnh nên được loại bỏ khi bạn rời khỏi phạm vi.

Nó giúp quản lý bộ nhớ tốt hơn và hiệu suất ứng dụng tốt hơn.

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

Nếu bạn có quá nhiều người theo dõi và bạn cần phải xóa tất cả chúng, bạn có thể đẩy chúng vào một mảng và phá hủy mọi thứ $watchtrong một vòng lặp.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.