intive Argentina Blog

Angular UI Router + ngAnimate bug

Es usual en nuestro trabajo encontrarnos con bugs, pero, en esta ocasión, me topé con uno particularmente feo en una aplicación. Lo que sucedió fue que, al navegar entre las distintas pantallas, el header con el nombre de la sección se borraba. El bug puede verse aún acá.

Tenemos entonces un state main que define el layout de la app: header, footer y el contenido en el medio. Al navegar, solamente se reemplaza el contenido, mientras que header y footer se mantienen.

Pero el header es dinámico. Para setearlo, cada sección escribe una variable en el scope de main y tiene la responsabilidad de dejarlo como estaba cuando el usuario navega hacia otra vista.

De no haber transiciones animadas entre las vistas, al navegar, el scope que sale es destruido y elscope de la vista que ingresa es creado. Se trata de un proceso sincrónico que acontece en ese orden.

Al incluir el módulo ngAnimate en el proyecto, uiRouter consideró que podría haber transiciones al navegar. Esto tiene dos implicancias:

  • El scope de la vista que entra es creado antes de que la animación de la vista que sale termine.
  • Elscope de la vista que sale es destruido cuando su animación termina.

Esta necesidad se da porque, si hubiera transiciones, ambas vistas convivirían. Si se destruyera el scope mientras una se va, se vería el template sin compilar. Respecto de este tema, podemos encontrar aquí una larga discusión.

En concreto, ¿cómo afectaba esto a mi app? La vista que entraba definía su header y luego, la saliente, lo reseteaba borrando lo que había definido la vista anterior.

En este caso particular, había agregado ngAnimate por necesidad de otros módulos, no porque la navegación fuera animada. Pero uiRouter mantiene su comportamiento, a menos que uno le especifique a cada uiView no animada con el atributo noanimation.

Escribir esto en cadauiView de la app no era tarea simple. En la discusión mencionada unas líneas más arriba, un dev ofreció una solución más simple:

Con esta directiva, se agrega el atributo noanimation a todas las uiView existentes y se resuelven nuestros problemas.

Me permito una aclaración que puede serles de utilidad: investigando, también descubrí que Angular permite tener más de una directiva con el mismo nombre, sin que se sobreescriban.

La versión final, que sólo consiste en agregar ese módulo, puede verse acá. ¡Happy coding! 🙂

Sebastián Bogado

Es desarrollador de full stack en intive – FDV. Ha trabajado con el stack de Javascript en varias plataformas (Televisores Smart & relojes Smart, NodeJS, aplicaciones híbridas móviles y – por supuesto – el navegador). En la actualidad estudia ingeniería informática en la Universidad de Buenos Aires (UBA), y está trabajando en su tesis de graduación.

Deja un comentario