start may have bootstrap application app angularjs scope

angularjs - may - ng app angular js



Alcance $ angular. $ Aplica frente a $ tiempo de espera como aplicaciĆ³n segura $ (3)

Estoy tratando de comprender mejor los matices del uso del servicio $ timeout en Angular como una especie de método de "aplicar $ seguro". Básicamente en escenarios donde un fragmento de código podría ejecutarse en respuesta a un evento angular o un evento no angular como jQuery o algún evento DOM estándar.

Como entiendo cosas:

  1. El código de ajuste en $ scope. $ Apply funciona bien para escenarios en los que todavía no se encuentra en un bucle de resumen (también conocido como evento jQuery) pero generará un error si un resumen está en progreso.
  2. El código de ajuste en una llamada $ timeout () sin parámetro de retraso funciona ya sea en un ciclo de resumen o no

Al observar el código fuente angular, parece que $ timeout realiza una llamada a $ rootScope. $ Apply ().

  1. ¿Por qué $ timeout () también genera un error si un ciclo de resumen ya está en curso?
  2. ¿Es la mejor práctica usar $ scope. $ Apply () cuando sabe con certeza que un compendio no estará en progreso y $ timeout () cuando lo necesita para estar seguro de cualquier manera?
  3. ¿Es $ timeout () realmente una "aplicación segura" aceptable, o hay errores?

Gracias por cualquier idea.


Al observar el código fuente angular, parece que $ timeout realiza una llamada a $ rootScope. $ Apply ().

  • ¿Por qué $ timeout () también genera un error si un ciclo de resumen ya está en curso?

$timeout hace uso de un $browser servicio angular no documentado. Específicamente, usa $browser.defer() que aplaza la ejecución de su función de forma asincrónica a través de window.setTimeout(fn, delay) , que siempre se ejecutará fuera del ciclo de vida angular. Solo cuando window.setTimeout haya window.setTimeout su función, $timeout call $rootScope.$apply() .

  • ¿Es la mejor práctica usar $ scope. $ Apply () cuando sabe con certeza que un compendio no estará en progreso y $ timeout () cuando lo necesita para estar seguro de cualquier manera?

Yo diría que sí. Otro caso de uso es que a veces necesitas acceder a una variable $ scope que sabes que solo se inicializará después del resumen. Un ejemplo simple sería si desea establecer el estado de un formulario sucio en el constructor de su controlador (por el motivo que sea). Sin $ timeout, FormController no se ha inicializado ni publicado en $ scope, por lo que al $scope.yourform.setDirty() dentro de $ timeout se asegura que FormController se haya inicializado. Claro que puedes hacer todo esto con una directiva sin $ timeout, solo dando otro ejemplo de caso de uso.

  • ¿Es $ timeout () realmente una "aplicación segura" aceptable, o hay errores?

Siempre debe ser seguro, pero su método ir siempre debe apuntar $ apply () en mi opinión. La aplicación Angular actual en la que estoy trabajando es bastante grande y solo hemos tenido que esperar $ timeout una vez en lugar de $ apply ().


Por lo que yo entiendo, $timeout es un wrapper alrededor de setTimeout que implícitamente llama $scope.$apply setTimeout , lo que significa que se ejecuta fuera del ciclo de vida angular, pero kickstarts el ciclo de vida angular en sí. El único "gotcha" que puedo pensar es que si esperas que tu resultado esté disponible este $digest , necesitas encontrar otra forma de "aplicar de forma segura" (que, AFAIK, solo está disponible a través de $scope.$$phase ).


Si usamos $, aplique mucho en la aplicación, podríamos obtener el error: $ digest ya en progreso. Sucede porque un ciclo $ digest se puede ejecutar a la vez. Podemos resolverlo por $ timeout o por $ evalAsync.

El $ timeout no genera errores como "$ digest ya en progreso" porque $ timeout le dice a Angular que después del ciclo actual, hay un tiempo de espera esperando y de esta manera se asegura que no habrá colisiones entre los ciclos de resumen y por lo tanto el resultado de $ el tiempo de espera se ejecutará en un nuevo ciclo $ digest.

Traté de explicarlos en: Comparación de aplicar, timeout, digest y evalAsync .

Puede ser que te ayude