스코프가 파괴 될 때 각도 $ watch를 제거해야합니까?
현재 파괴 된 범위에서 브로드 캐스트 구독을 지우지 않을 때 엄청난 메모리 누수가 발견 된 프로젝트를 진행 중입니다. 다음 코드는이 문제를 해결했습니다.
var onFooEventBroadcast = $rootScope.$on('fooEvent', doSomething);
scope.$on('$destroy', function() {
//remove the broadcast subscription when scope is destroyed
onFooEventBroadcast();
});
이 관행을 시계에도 사용해야합니까? 아래 코드 예 :
var onFooChanged = scope.$watch('foo', doSomething);
scope.$on('$destroy', function() {
//stop watching when scope is destroyed
onFooChanged();
});
아니요, $$watchers
스코프가 파괴되면 효과적으로 제거되므로 제거 할 필요가 없습니다 .
Angular의 소스 코드 (v1.2.21)에서 Scope
의 $destroy
방법 :
$destroy: function() {
...
if (parent.$$childHead == this) parent.$$childHead = this.$$nextSibling;
if (parent.$$childTail == this) parent.$$childTail = this.$$prevSibling;
if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling;
if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling;
...
this.$$watchers = this.$$asyncQueue = this.$$postDigestQueue = [];
...
따라서 $$watchers
배열이 비워지고 범위가 범위 계층에서 제거됩니다.
watcher
배열에서를 제거하는 것은 어쨌든 등록 해제 기능이 수행하는 모든 것입니다.
$watch: function(watchExp, listener, objectEquality) {
...
return function deregisterWatch() {
arrayRemove(array, watcher);
lastDirtyWatch = null;
};
}
따라서 $$watchers
"수동" 등록을 취소 할 필요가 없습니다 .
그래도 이벤트 리스너 등록을 취소해야합니다 (게시물에서 올바르게 언급했듯이)!
참고 : 다른 범위에 등록 된 리스너 만 등록 취소하면됩니다. 소멸되는 범위에 등록 된 리스너를 등록 취소 할 필요가 없습니다.
예 :
// You MUST unregister these
$rootScope.$on(...);
$scope.$parent.$on(...);
// You DON'T HAVE to unregister this
$scope.$on(...)
( 지시 를 위해 @John에게 감사합니다 )
또한 소멸되는 범위보다 오래 지속되는 요소에서 이벤트 리스너를 등록 취소해야합니다. 예를 들어 지시문이있는 경우 상위 노드 또는에 리스너를 등록한 <body>
다음 등록을 취소해야합니다.
다시 말하지만, 소멸되는 요소에 등록 된 리스너를 제거 할 필요가 없습니다.
원래 질문과는 관련이 없지만 이제 $destroyed
파괴되는 요소에 전달 되는 이벤트 도 있으므로 여기에 연결할 수 있습니다 (사용 사례에 적합한 경우).
link: function postLink(scope, elem) {
doStuff();
elem.on('$destroy', cleanUp);
}
@gkalpak 의 답변 을 추가하고 싶습니다 .
내가 작업하고 있던 응용 프로그램은 감시자가있는 지시문을 대체하여 메모리 누수를 일으켰습니다. 지시문은 jQuery를 사용하여 대체 된 다음 준수되었습니다.
수정하기 위해 다음 링크 기능을 추가했습니다.
link: function (scope, elem, attrs) {
elem.on('$destroy', function () {
scope.$destroy();
});
}
요소 destroy 이벤트를 사용하여 범위를 차례로 삭제합니다.
참조 URL : https://stackoverflow.com/questions/25113884/should-angular-watch-be-removed-when-scope-destroyed
'IT이야기' 카테고리의 다른 글
Windows 8.1에서 빌드되지 않는 노드 패키지-Microsoft.Cpp.Default.props 누락 (0) | 2021.04.29 |
---|---|
Angular 지시문 요소에 속성을 추가하는 방법 (0) | 2021.04.29 |
==를 기본 및 boxed 값에 사용할 때, autoboxing 완료 또는 unboxing 완료 (0) | 2021.04.28 |
Bitbucket 저장소가 "원격 : 잘못된 암호 시도 횟수가 너무 많습니다. (0) | 2021.04.28 |
'@ angular / common / http'모듈을 찾을 수 없습니다. (0) | 2021.04.28 |