결론만 알고 싶다면
$scope.$watch($rootScope.xxx,function(newVal,oldVal){ //do something })
누군가 즉시 왜 안 되는지 물었습니다.
$rootScope.$watch("xxx",function(newVal,oldVal){ //do something })
최근 발생한 버그 중 첫 번째 방법을 사용해야 하는 이유를 알려드리겠습니다.
논리는 그림과 같습니다. 처음에는 $rootScope.$watch라는 작성 방법을 사용했습니다. $rootScope에 대한Angularjs의 감시는 일단 등록되면 전역적으로 유효하기 때문입니다. 그리고 내 전역 변수는 주문 정보입니다. 즉, 서로 다른 컨트롤러에 변경 사항이 있고 모든 변경 사항이 $rootScope.$watch를 트리거하여 다른 컨트롤러로 들어가게 됩니다. 비유하자면 $rootScope의 $broadcast는 전역적으로 시작됩니다.
사실 이 방법만이 유일한 것은 아닙니다. 다음 코드를 포함해 Angular 소스코드를 확인해보면 watch 메소드 소스코드를 찾는 것은 어렵지 않습니다.
return function deregisterWatch() { if (arrayRemove(array, watcher) >= 0) { incrementWatchersCount(scope, -1); } lastDirtyWatch = null; };
이 코드는 수동으로 시계를 청소하는 것이 가능함을 알려줍니다. 예:
var watcher = $rootScope.$watch("xxx",function(){}); //手动清除 watcher watcher();
아직도 매우 간단합니다. 위의 방법은 스코프 시계에도 사용할 수 있습니다.
이 점을 조사했을 때 문제가 있다고 느꼈습니다. 내 $scope가 지워지나요? 그래서 소스코드를 계속 살펴보니 $destroy 메소드에서 다음 코드를 발견했습니다.
// Disable listeners, watchers and apply/digest methods this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop; this.$on = this.$watch = this.$watchGroup = function() { return noop; }; this.$$listeners = {};
위 코드는 이 글에서 소개한 범위로 모니터링할 Angularjs 전역 변수의 올바른 자세입니다. 이 글이 잘 작성되지 않은 경우 조언을 부탁드립니다.