ChatGPT解决这个技术问题 Extra ChatGPT

AngularJS:清除 $watch

我的 AngularJS 应用程序中有一个监视功能。

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

但是,在某些情况下(在我的示例中,更改我的 single-page application 处的页面)我想停止那个手表(就像清除超时一样)。

我怎样才能做到这一点?


P
Peter Mortensen

$watch 返回一个注销函数。调用它会注销 $watcher

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

您知道在控制器生命周期结束时(例如在 $on('$destroy') 上)取消注册所有侦听器是一种好习惯,还是 AngularJS 会处理它们?谢谢!
当作用域被销毁时,所有的观察者都将被删除,你不需要管理那些
您可以在这里看到一个有趣的讨论来解释这个问题:github.com/angular/angular.js/issues/4574 基本上,如果您为 $rootScope 分配一个侦听器,您必须自己取消分配它,否则它将在 $scope 更改中持续存在。 $scope 上的观察者会被 $scope 销毁($scope 不是 Angular 中的单例,它们会在需要时被创建和销毁)。
但是,如果我只希望观察者检查值是否存在,然后当它存在时做一些更改,然后注销自己我已经尝试过 - var listen = $scope.$watch('mvIdentity.currentUser', function(currentUser ) { test = 1; console.log("--> " + $scope.updateemail + " -- " + test); listen(); });
@UmurKontacı 实际上,deadman 的评论完全有效,因为您的原始评论并非对每种情况都正确。
A
Anders Ekdahl

scope.$watch 返回一个您可以调用的函数,该函数将取消注册手表。

就像是:

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

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

是的,您可以在 watchFn 中解除绑定!简单用例:您只想观看并执行一次 watchFn,然后停止观看。
调用 unbind 函数后是否可以重新绑定手表,比如再次调用它?
这很有用。在我的测试中,超时执行 unbindWatch 似乎很重要。
在这种情况下,您应该使用 $timeout,您也可以取消注册!
最好避免超时
S
SoEzPz

如果您想在发生某些事情后立即清除它,您也可以清除回调中的手表。这样,您的 $watch 将保持活动状态,直到使用为止。

像这样...

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!
  } 
}

n
naCheex

有时您的 $watch 正在调用 dynamically 并且它将创建它的实例,因此您必须在 $watch 函数之前调用取消注册函数

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

M
Manish Kumar

理想情况下,当您离开示波器时,应移除每个自定义手表。

它有助于更好的内存管理和更好的应用程序性能。

// 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
});

D
Danilo Cândido

如果您有太多的观察者并且需要清除所有观察者,您可以将它们推入一个数组并销毁循环中的每个 $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 = [];