Angularjs全局变量被作用域监听的正确姿势
如果你只想知道结论:
$scope.$watch($rootScope.xxx,function(newVal,oldVal){
//dosomething
})
马上就有人问为什么不是:
$rootScope.$watch("xxx",function(newVal,oldVal){
//dosomething
})
从我最近的一个bug来说说为什么要用第一种方式。
逻辑如图,一开始我使用了$rootScope.$watch的写法。因为angularjs在$rootScope上的watch一旦注册全局有效。而我的这个全局变量恰好是订单信息,也就是说不同的controller对他都是有改动的,每一次改动就会触发$rootScope.$watch进入别的controller。可以类比看一下$rootScope上的$broadcast会全局出发的。
其实这并不是唯一的方式,查一下angular源码不难找到watch方法源码不分有如下代码:
returnfunctionderegisterWatch(){
if(arrayRemove(array,watcher)>=0){
incrementWatchersCount(scope,-1);
}
lastDirtyWatch=null;
};
这段代码告诉我们,手动清理watch是可行的。例如:
varwatcher=$rootScope.$watch("xxx",function(){});
//手动清除watcher
watcher();
还是很简单对吧,以上方法同样可以用于scope上的watch。
研究到这里的时候,觉得有点问题,那我在$scope会被清理么?于是呼,继续翻源码,我在$destroy方法里面找到如下代码:
//Disablelisteners,watchersandapply/digestmethods
this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=noop;
this.$on=this.$watch=this.$watchGroup=function(){
returnnoop;
};
this.$$listeners={};
以上代码是本文给大家介绍的Angularjs全局变量被作用域监听的正确姿势,希望大家有所帮助,本文写的不好还请各位大侠多多指教。