angularJS $on 이벤트 핸들러 트리거 순서
나는 두가지를 궁금했어요, 각도의JS 이벤트 처리.
- 동일한 이벤트를 청취하는 핸들러가 트리거되는 순서는 어떻게 정의됩니까?
- 이것에 대해 궁금증을 가지기 시작하면 디자인이 좋지 않다는 신호입니까?
각 $on, $broadcast 및 $emit에 대한 설명서와 네이티브 DOM 이벤트 흐름을 읽고 어떤 순서로 이벤트 핸들러가 다른 범위에서 트리거되는지 이해했다고 생각합니다.문제는 여러 핸들러가 동일한 범위(예: rootScope)에서 다양한 장소(예: Controller vs Services)에서 수신하는 경우입니다.
문제를 설명하기 위해 하나의 컨트롤러와 두 개의 서비스로 jsfiddle을 구성했으며 모두 $rootScope http://jsfiddle.net/Z84tX/ 을 통해 통신했습니다.
Thanks
아주 좋은 질문입니다.
이벤트 핸들러는 초기화 순서대로 실행됩니다.
제 핸들러들이 어떤 핸들러가 먼저 실행되는지 알 필요가 없었기 때문에 이 문제에 대해 별로 생각해 본 적이 없지만, 핸들러들이 초기화되는 순서대로 호출되는 것을 볼 수 있습니다.
당신은 조종 장치를 가지고 있습니다.controllerA
두가지 서비스에 달려있는거죠ServiceA
그리고.ServiceB
:
myModule
.controller('ControllerA',
[
'$scope',
'$rootScope',
'ServiceA',
'ServiceB',
function($scope, $rootScope, ServiceA, ServiceB) {...}
]
);
서비스와 컨트롤러 모두 이벤트 수신기를 정의합니다.
이제 모든 종속성을 해결한 후 주입해야 합니다. 즉, 컨트롤러에 주입하기 전에 두 서비스가 모두 초기화됩니다.따라서 서비스 팩토리는 컨트롤러보다 먼저 초기화되기 때문에 서비스에 정의된 핸들러가 먼저 호출됩니다.
그러면 투입되는 순서대로 초기화가 되는 것을 볼 수 있습니다.ServiceA
이전에 초기화됩니다.ServiceB
그 순서대로 컨트롤러에 주입되기 때문입니다.컨트롤러 서명 내에서 순서를 변경하면 초기화 순서도 변경됩니다(ServiceB
앞에 오는ServiceA
).
따라서 서비스가 초기화된 후 컨트롤러도 초기화되고 이를 통해 이벤트 핸들러가 내부에 정의됩니다.
따라서 $broadcast에서 핸들러는 다음과 같은 순서로 실행됩니다.ServiceA
핸들러,ServiceB
핸들러,ControllerA
조련사
이 경로로 가는 것은 좀 번거롭지만, 서비스 B가 서비스 A 이전에 초기화되는지 확인할 수 없고 서비스 B의 청취자가 먼저 실행되어야 하는 경우를 대비하여 대안을 제공하고자 했습니다.
당신이 조작할 수 있는 것은$rootScope.$$listeners
서비스 B의 청취자를 최우선으로 하는 배열.
청취자를 에 추가할 때 이와 같은 것이 작동합니다.$rootScope
서비스 중 B:
var listener, listenersArray;
$rootScope.$on('$stateChangeStart', someFunction);
listenersArray = $rootScope.$$listeners.$stateChangeStart;
listener = listenersArray[listenersArray.length - 1];
listenersArray.splice(listenersArray.length - 1, 1);
listenersArray.unshift(listener);
#2에 대한 답을 제공하기 위해(#1에 대한 @Stewie의 답이 정말 좋은 것이라고 생각하기 때문에), "이것을 보면 나쁜 코드"라는 결정적인 규칙을 제안하는 것을 망설이고 있지만, 만약 두 명의 이벤트 핸들러가 있다면,그리고 하나는 다른 하나가 실행된 후에만 실행할 수 있습니다. 왜 그런 것인지, 그리고 논리가 실행되는 방식을 더 잘 캡슐화하거나 구성할 수 없는 경우를 평가해야 합니다.
pub/sub event 브로드캐스트/리스닝의 주요 사용 사례 중 하나는 서로 완전히 독립적인 별개의 구성 요소가 그들의 영향 영역에서 비동기적인 방식으로 작동하도록 허용하는 것입니다.한 핸들러는 다른 핸들러가 먼저 실행된 후에만 작동해야 하므로 보조 요구사항을 추가하여 pub/sub의 비동기성을 제거하는 것입니다(가능한 경우 필요함).
꼭 필요한 종속성이라면 아닙니다. 디자인이 나쁘다는 증상이 아니라 해당 기능의 요구 사항에 따른 증상입니다.
Angular JS를 처음 사용하는 사용자이므로 답변이 최적에 못 미치더라도 양해 부탁드립니다. :P
이벤트에 의해 트리거된 함수의 순서를 종속적으로 설정해야 하는 경우(즉, 함수 A, 함수 B) 트리거 함수를 생성하지 않는 것이 더 나을 수 있습니다.
function trigger(event,data) {
FunctionA(event,data);
FunctionB(event,data);
}
$rootScope.on('eventTrigger',trigger);
2번 지점에 대한 다른 의견을 추가하려면 순서를 보장해야 할 경우 청취자 배열이 있는 서비스를 사용하여 관찰자 패턴을 구현할 수 있습니다.서비스에서 청취자가 순서를 지정하는 방법을 정의하는 "addListener" 함수를 정의할 수 있습니다.그런 다음 이벤트를 수행하는 데 필요한 다른 구성 요소에 이 서비스를 주입할 수 있습니다.
디자인에 사용하는 것은 절대 권장되지 않지만 선택의 여지가 없을 때도 있습니다.
$rootScope.$on('someEvent', () => {
setTimeout(eventHandler1, 1);
});
$rootScope.$on('someEvent', eventHandler2);
const eventHandler1 = () => {
console.log('This one runs last');
};
const eventHandler2 = () => {
console.log('This one runs first');
};
예를 보시면 아시겠지만, 저는 지금까지setTimeout
실제 핸들러를 실행하는 순서를 속이고 다음을 만듭니다.eventHandler1
먼저 호출되었지만 마지막으로 실행할 핸들러입니다.
실행 우선 순위를 설정하려면 다음 항목을 변경합니다.setTimeout
필요에 따라 연기합니다.
이는 이상적이지 않으며 특정한 경우에만 적합합니다.
언급URL : https://stackoverflow.com/questions/17451382/angularjs-on-event-handler-trigger-order
'programing' 카테고리의 다른 글
malloc은 메모리를 할당하는 동안 더 많은 공간을 확보합니까? (0) | 2023.11.05 |
---|---|
jQuery의 ajax success callback에서 textStatus가 "success"가 되지 않을 수 있습니까? (0) | 2023.11.05 |
wocommerce는 rest api를 통해 사용자 이름과 비밀번호를 확인합니다. (0) | 2023.11.05 |
MySQL의 원시 바이너리 플로트 데이터 액세스 (0) | 2023.11.05 |
C 표준은 n개 요소 배열의 크기가 요소 크기의 n배가 되도록 요구합니까? (0) | 2023.11.05 |