AngularJS: Ясний $ годинник


277

У моїй програмі AngularJS у мене є годинник.

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

Однак після певної умови (в моєму прикладі, зміни сторінки в моїй односторінковій програмі ) я хочу зупинити цей перегляд (як, наприклад, очищення тайм-ауту).

Як я можу це зробити?

Відповіді:


520

$watchповертає функцію зняття реєстрації. Якщо зателефонувати, це скасує реєстрацію $watcher.

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

24
Чи знаєте ви, чи є гарною практикою скасування реєстрації всіх ваших слухачів наприкінці життєвого циклу контролера (наприклад, на a $on('$destroy')) чи AngularJS подбає про них? Дякую!
йорч

81
Усі спостерігачі будуть видалені, коли область буде знищена, вам не потрібно керувати ними
Umur Kontacı

6
Тут ви можете побачити цікаву дискусію, яка пояснює цю проблему: github.com/angular/angular.js/isissue/4574 В основному, якщо ви призначите слухача $ rootScope, вам доведеться скасувати призначення себе, інакше воно збережеться через $ зміни обсягу. Охоронці на $ range знищуються за допомогою $ range (область застосування $ не є однотонними в Angular, і вони створюються та знищуються при необхідності).
Младен Данич

3
Але що робити, якщо я хочу лише, щоб спостерігач перевіряв, чи існує значення, а потім, коли він існує, зробити деякі зміни, а потім зареєструвати себе, я вже спробував - var liste = $ obseg. $ Watch ('mvIdentity.currentUser', функція (currentUser ) {test = 1; console.log ("->" + $ range.updateemail + "-" + тест); liste ();});
Харшит Ладдха

4
@ UmurKontacı Насправді коментар мертвяка цілком справедливий, оскільки ваш оригінальний коментар невірний для кожного випадку.
GFoley83

49

$ watch повертає функцію, яку ви можете зателефонувати, і яка скасує реєстрацію годинника.

Щось на зразок:

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

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

14
Так, ви можете від’єднати всередині watchFn! Простий випадок використання: ви хочете дивитися та виконувати watchFn лише один раз, а потім перестати дивитися.
Майк Рападас

3
Чи я можу відновити годинник після того, як я зателюю функцію відключення, як, наприклад, знову зателефонувати?
Бруно Фінгер

Це було корисно. Робота unbindWatch у таймауті здається важливою для мого тестування.
eeejay

У цьому випадку ви повинні використовувати $ timeout, який ви також можете скасувати!
Бен Таліадорос

Краще уникати тайм-аутів
Даві Ліма

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.