angularjs - cloak - ng-required angular 4
angularJS $ en la orden de activaciĆ³n del controlador de eventos (5)
Me preguntaba dos cosas, en el contexto del manejo de eventos angularJS.
- ¿Cómo se define el orden en que se desencadenan los controladores que escuchan el mismo evento?
- ¿Es un signo de un mal diseño si empiezas a preguntarte sobre esto?
Después de leer la documentación sobre $ angular on, $ broadcast y $ emit , así como el flujo de eventos DOM nativos, creo que entiendo en qué orden los manejadores de eventos se activarán en diferentes ámbitos. El problema es cuando varios manejadores escuchan en el mismo ámbito ($ rootScope por ejemplo) desde varios lugares (Controladores vs Servicios, por ejemplo).
Para ilustrar el problema, he reunido un jsfiddle con un controlador y dos servicios, todos comunicados a través de $ rootScope http://jsfiddle.net/Z84tX/
Thanks
Es un poco complicado (y no lo recomendaría) ir por esta ruta, pero quería ofrecer una alternativa en caso de que no pueda garantizar que el servicio B se inicialice antes del servicio A y que absolutamente necesite que el oyente del servicio B se ejecute primero.
Puede manipular la matriz de $rootScope.$$listeners
para poner primero el oyente de serviceB.
Algo así funcionaría al agregar el oyente a $rootScope
en serviceB:
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);
Muy buena pregunta.
Los manejadores de eventos se ejecutan en orden de inicialización.
Realmente no había pensado en esto antes, porque mis manejadores nunca necesitaron saber cuál correr primero, pero con la mirada de su violín puedo ver que los manejadores son llamados en el mismo orden en el que se inicializaron.
En tu violín tienes un controlador controllerA
que depende de dos servicios, ServiceA
y ServiceB
:
myModule
.controller(''ControllerA'',
[
''$scope'',
''$rootScope'',
''ServiceA'',
''ServiceB'',
function($scope, $rootScope, ServiceA, ServiceB) {...}
]
);
Ambos servicios y el controlador definen un detector de eventos.
Ahora, todas las dependencias deben resolverse antes de ser inyectadas, lo que significa que ambos servicios se inicializarán antes de ser inyectados en el controlador. Por lo tanto, los manejadores definidos en los servicios serán llamados primero, porque las fábricas de servicios se inicializan antes que el controlador.
Luego, también puede observar que los servicios se inicializaron para que se inyectaran. Entonces ServiceA
se inicializa antes de ServiceB
porque se inyectan en ese orden en el controlador. Si cambió su orden dentro de la firma del controlador, verá que su orden de inicio también se cambia ( ServiceB
viene antes de ServiceA
).
Entonces, después de que se inicialicen los servicios, el controlador se inicializa también, y con él, el controlador de eventos definido dentro.
Entonces, el resultado final es que, en $ broadcast, los manejadores se ejecutarán en este orden: ServiceA
handler, ServiceB
handler, ControllerA
handler.
Para agregar otro comentario sobre el punto n. ° 2, si necesita garantizar el orden, puede implementar un patrón de observador utilizando un servicio con una variedad de oyentes. En el servicio, puede definir las funciones "addListener" que también definen cómo se ordenan los oyentes. Luego puede inyectar este servicio en cualquier otro componente que necesite para activar eventos.
Para dar una respuesta al # 2 (porque creo que la respuesta de @ Stewie al # 1 es realmente buena), aunque dudaría en ofrecer alguna vez reglas concluyentes que digan "si ves esto, entonces es un código incorrecto", ofrecería decir que si tiene dos manejadores de eventos, y uno solo puede ejecutar después de que el otro se haya ejecutado: debe evaluar por qué es así y si no puede encapsular u organizar mejor la forma en que se ejecuta su lógica.
Uno de los principales casos de uso de la difusión / escucha de los eventos pub / sub es permitir que los componentes independientes sean totalmente independientes unos de otros para operar en su dominio de influencia de manera independiente de forma asincrónica. Si un manejador tiene que operar solo después de que se haya ejecutado otro controlador, está eliminando la naturaleza asíncrona de pub / sub agregando un requisito secundario (aunque posiblemente sea necesario).
Si se trata de una dependencia absolutamente necesaria, entonces no: no es un síntoma de un mal diseño: es un síntoma de los requisitos de esa característica .
Soy un nuevo usuario de Angular JS, así que, por favor, perdona si la respuesta es menos que óptima. :PAG
Si requiere que el orden de las funciones activadas por un evento sea dependiente (es decir, la Función A y luego la Función B), entonces ¿no sería mejor crear una función de disparo?
function trigger(event,data) {
FunctionA(event,data);
FunctionB(event,data);
}
$rootScope.on(''eventTrigger'',trigger);