Queremos emitir algunas llamadas $ http en el bloque de ejecución del módulo, idealmente, la ejecución debería finalizar solo después de que $ http y el procesamiento finalice antes de que ocurra la compilación de dom.
Esto no es tan fácil, pero debería analizarse.
La forma en que Jasmine hace esto es estableciendo una bandera, que permitirá que la función se ejecute y esperará la devolución de llamada hasta que la bandera se establezca en true
, o hasta que se dispare un tiempo de espera.
Básicamente algo como esto:
var flag = false;
$http(...).success(flag = true);
$timeout(function () {
flag = true;
// Or add some error handling stuff here
}, 5000);
while (!flag) {};
No es bonito, pero debería hacer el trabajo. El código anterior no se ha probado, por lo que es posible que deba modificarlo un poco. Se hace tarde aquí. Con suerte, algo para ayudarte hasta que aparezca algo un poco más bonito.
+1
Sin embargo, en un segundo, esto conduce a la incapacidad de dibujar una pantalla de carga elegante utilizando directivas angulares ...
+1
¿No resuelve esto $routeProvider
con resolve
? Quizás no entendí el problema ...
Esto es más para el soporte de inicio de módulo asíncrono. Dicho esto, ya no necesito esto en mis proyectos actuales.
@shahata $routeprovider
hace esto, pero no todos los casos de uso para hacer promesas run
s usan rutas. En mi caso de uso, es para un módulo que envuelve una directiva y no tiene nada que ver con las rutas.
+1
compruebe si la función de ejecución devuelve una promesa, luego solo proceda cuando se resuelva. dado que runBlocks
es una matriz de funciones, no debería ser difícil en absoluto
+1
+1 vergonzoso que esto haya sido ignorado
¿Alguna idea de cuándo va a aterrizar esto? es muy frustrante tener que mover las cosas de inicialización para resolverlas en el enrutador, principalmente porque a veces el código de inicialización es independiente de la URL (también conocido como, debe inicializarse para cualquier tipo de URL que el usuario llegue a su SPA)
No creo que angular reciba mejoras a partir de ahora. todos se agregan a angular 2.0
¿Cuánto tiempo permanecerá sincrónico el método run
medias? Está bien y es comprensible que config
no admita llamadas asincrónicas, ya que no tiene proveedores que hagan llamadas $http
, pero run
sí. mire el tipo de hacks que causa la falta de esta característica (que debería haber estado desde el principio)
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js
es vergonzoso
+1
@btford está analizando cómo los casos de uso relacionados con esto podrían ser compatibles a través del nuevo enrutador en lugar de dentro de los bloques de ejecución.
+1
+1
+1
+1
El principal problema que tenemos es que $q
se crea dentro de un módulo que se está cargando cuando se ejecutan los runBlocks. Esto significa que tendríamos que extraer de alguna manera "algunos" de los servicios (o quizás módulos) y crearlos primero y luego tener una segunda pasada que cargue el resto de los módulos (y servicios, ejecutar bloques, etc.) después de que $ q haya sido creado.
@lgalfaso , ¿quizás podrías investigar esto un poco más como parte de tu trabajo $injector
más adelante esta semana (o la próxima)?
Sé que es solo una solución, pero normalmente resolví el problema de tener alguna lógica de arranque asíncrono usando un enrutador de interfaz de usuario angular y tener un estado abstracto de raíz en combinación con resolver. El estado abstracto raíz siempre debe resolverse primero, por lo que es un buen lugar para cargar configuraciones, mostrar animaciones de carga, etc.
Esto sería genial.
: +1:
Esperando esta solución. Espero que llegue en 1.4
+1
Tengo otro caso de uso: necesito iniciar mis puntos finales simulados con una llamada $ http al inicio (para almacenar en caché algunos datos) ...
+1
+1
acaba de tropezar con esto también ...
@petebacondarwin creo que estaría bien continuar cargando todos los demás módulos, pero aplazar el inicio de la navegación inicial.
alternativamente, $ routeProvider podría ofrecer un parámetro de función configurable que debería posponer la representación de la ruta inicial.
+1
+1
Aquí hay una posible solución: http://plnkr.co/edit/vi7mDjmD4NpZAoP7MVzr?p=preview
La idea es que Angular te da la posibilidad de crear tu propio inyector a partir de un conjunto de módulos. En este caso, he retrasado la compilación de $rootElement
hasta que se hayan resuelto un montón de promesas ( resolves
). Este es un POC y habría una serie de otras campanas y silbidos que serían necesarios para que esta producción esté lista. Aparte de cualquier otra cosa, necesitaría detectar errores en las resoluciones en lugar de simplemente tragarlos.
+1
Esta es principalmente una guía para quien quiera intentarlo; Actualmente, el proceso de arranque hace lo siguiente:
$rootElement
$rootElement
En la parte superior, al crear el inyector los pasos son los siguientes:
run
para más tarderun
Hay algunos puntos clave:
run
se ejecutan antes de que se compile $rootElement
$rootElement
$q
resuelve promesas durante un ciclo de resumen _only_Este es:
run
que devuelve una promesa y la promesa debe resolverse antes de que se inicie la aplicación, habrá ciclos de resumen antes de la compilación inicial (esto puede romper las aplicaciones existentes)config
se inyecta con proveedores, no con instanciasCualquiera que sea la solución, necesita manejar estos casos
+1
¿hay noticias?
Solo quiero cargar algunas configuraciones de configuración antes de que la aplicación realmente comience.
+1
Cargaría algunos datos asíncronos después del arranque cuando todas mis fábricas estén funcionando y antes de la compilación.
@dagingaa : ¡Creo que elegiría su solución como solución alternativa! Gracias
Actualización a @dagingaa : el bucle for congela mis navegadores, no es bueno ...
https://jsfiddle.net/tuxmachine/t4d63vnw/
Así es como lo resolví para una implementación de token de OAuth, que requería que se resolviera una llamada ajax inicial antes de inicializar el resto de la aplicación.
Sin embargo, no funcionará si tiene varios bloques de ejecución asíncronos
+1
+1
+1
Han pasado dos años desde que se abrió el problema y todavía no hay una buena solución.
@vladmiller Hay soluciones pero quizás no sientes que son buenas:
$onActivate
en el componente de nivel superiorPoner el trabajo de la aplicación no trivial dentro de los bloques .run
dificulta la prueba unitaria de su código. Por tanto, no es algo que queramos fomentar. Mover esto a la caja de hielo como algo que probablemente no implementemos.
@petebacondarwin No estoy de acuerdo contigo; todos esperan que angluar sea simple e intuitivo, en su lugar, debe implementar su propio módulo de arranque asíncrono o módulo de arranque en un lugar diferente. En mi opinión, esto hace que angular sea más complejo.
¿También puede explicar qué quiere decir cuando dice que el código asíncrono en .run
hará que las pruebas sean más difíciles?
Disculpas por mi anterior comentario grosero.
Gracias
@petebacondarwin No veo cómo dificulta la prueba. Si coloca el código de inicialización en un servicio, puede simplemente ver / simular / comparar los resultados que espera del simulacro de backend http, independientemente de si se está ejecutando dentro de un bloque .run
o no. el hecho de que el código exista fuera de angular debido a soluciones temporales por la falta de ejecución asíncrona es lo que hace que sea casi imposible de probar
¿Cómo va?
Otro enfoque: http://plnkr.co/edit/8XGSNOzzRGvgNSSnXx3M?p=preview
La solución
Dado que existen soluciones alternativas y el soporte de bloques de ejecución asíncrona agregaría complejidad al bootstrap, no creo que implementemos esta función.
Característica simple pero demasiado difícil de implementar. 😕
+1 para esta función
+1
+1
La solución
+1. :(
+1
+1
+1
+1
No vamos a hacer esto.
+100, todas las soluciones son terribles.
@ Eduardo-Julio: no vamos a implementar esta función, ya que haría mucho más complejo el arranque de las aplicaciones AngularJS. Agregar más +
s no ayudará.
Comentario más útil
Característica simple pero demasiado difícil de implementar. 😕