편집 :이 답변에서 해결 된 문제는 angular.js 버전 1.2.7 에서 해결되었습니다 . $broadcast
이제 등록되지 않은 범위에서 버블 링을 피하고 $ emit만큼 빠르게 실행됩니다.
이제 다음을 수행 할 수 있습니다.
- 사용하다
$broadcast
으로부터$rootScope
- 행사에 대해 알아야
$on
할 현지인의$scope
말을 들어보십시오
아래의 원래 답변
$rootScope.$broadcast
+ 를 사용 $scope.$on
하지 말고 $rootScope.$emit
+ 를 사용하는 것이 $rootScope.$on
좋습니다. 전자는 @numan으로 인해 심각한 성능 문제를 일으킬 수 있습니다. 이벤트가 모든 것을 통해 버블 링되기 때문입니다 범위에서 입니다.
그러나 후자 ( $rootScope.$emit
+ 사용 $rootScope.$on
)는이 문제를 겪지 않으므로 빠른 통신 채널로 사용할 수 있습니다!
의 각도 문서에서 $emit
:
스코프 계층을 통해 이벤트 이름을 위쪽으로 전달하여 등록되었음을 알립니다.
위의 범위 $rootScope
가 없으므로 버블 링이 발생하지 않습니다. $rootScope.$emit()
/ $rootScope.$on()
EventBus 로 사용하는 것이 안전합니다 .
그러나 컨트롤러 내에서 사용할 때 한 가지 문제가 있습니다. $rootScope.$on()
컨트롤러 내에서 직접 바인딩하는 경우 로컬에서 바인딩을 직접 정리해야합니다.$scope
이 손상 . 이는 서비스와 달리 컨트롤러가 응용 프로그램 수명 동안 여러 번 인스턴스화 될 수 있기 때문에 바인딩이 합쳐져 결국 모든 곳에서 메모리 누수가 발생하기 때문입니다. :)
등록을 취소, 당신의 청취 $scope
의 $destroy
이벤트 다음에 의해 반환 된 함수를 호출합니다 $rootScope.$on
.
angular
.module('MyApp')
.controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {
var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
console.log('foo');
});
$scope.$on('$destroy', unbind);
}
]);
다른 EventBus 구현에도 적용되므로 리소스를 정리해야한다는 것은 특정 각도가 아닙니다.
그러나 그러한 경우 삶을 더 편하게 만들 수 있습니다 . 예를 들어, 원숭이 패치를 수행 $rootScope
하여에 생성 $onRootScope
된 이벤트를 구독 $rootScope
하고 로컬에있을 때 핸들러를 직접 정리할 수 있습니다.$scope
이 파괴 있습니다.
$rootScope
그런 $onRootScope
방법 을 제공하기 위해 원숭이 패치를하는 가장 깨끗한 방법 은 데코레이터를 사용하는 것입니다 (실행 블록은 아마 잘 할 것입니다.
있는지 확인하려면 $onRootScope
이상 열거하는 속성이 예상치 못한 표시되지 않습니다 $scope
우리가 사용 Object.defineProperty()
하고 설정 enumerable
에 false
. ES5 심이 필요할 수 있습니다.
angular
.module('MyApp')
.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
value: function(name, listener){
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
return unsubscribe;
},
enumerable: false
});
return $delegate;
}]);
}]);
이 방법을 사용하면 위의 컨트롤러 코드를 다음과 같이 단순화 할 수 있습니다.
angular
.module('MyApp')
.controller('MyController', ['$scope', function MyController($scope) {
$scope.$onRootScope('someComponent.someCrazyEvent', function(){
console.log('foo');
});
}
]);
그래서 모든이의 최종 결과로 내가보기 엔 사용하도록 조언 $rootScope.$emit
+$scope.$onRootScope
.
Btw, 나는 각진 팀이 각진 핵심 내의 문제를 해결하도록 설득하려고 노력하고 있습니다. https://github.com/angular/angular.js/issues/4574 에 대한 토론이 있습니다.
다음은 $broadcast
괜찮은 시나리오에서 100 $scope
의 성능으로 테이블에 미치는 영향의 정도를 보여주는 jsperf입니다 .
http://jsperf.com/rootscope-emit-vs-rootscope-broadcast