Skip to content
Aprende a hacer apps móviles con Ionic 2 

Navegación en Ionic 2: lifecycle events

Las vistas de aplicaciones nativas (iOS, Android) tienen un ciclo de vida bien estructurado que permite realizar acciones en momentos clave de su ejecución. Ionic 2 cuenta con una característica equivalente: Los lifecycle events de navegación.

iOS view lifeCycle

En Ionic 2, cualquier vista que se añade o quita a un NavController emite ciertos eventos que puedes aprovechar para inicializar la vista, refrescar contenido o guardar datos, por ejemplo.

Enseguida descubrirás como usarlos gracias a un ejemplo hands-on code, pero primero… ¡vamos a profundizar en el tema!

Lifecycle events

Los eventos de navegación de Ionic 2 son muy similares a los que define iOS. Aquí tienes un diagrama que muestra como funcionan.

ionic2 View Lifecycle Events

Resumiendo, los eventos son estos:

  • ionViewDidLoad: Se llama únicamente cuando cargas una página en memoria (push). Este evento NO se lanza si entras por segunda vez en una vista que ya está cacheada. Es un buen sitio para tareas relacionadas con la inicialización de la vista.

  • ionViewWillEnter: Se ejecuta cuando entras en una página, antes de cargarla. Utilízalo para tareas que se deben realizar siempre que entras en la vista, exista ya o no (activar listeners de eventos, actualizar una tabla, etc).

  • ionViewDidEnter: Se ejecuta cuando entras en una página, después de cargarla. Ahora ésta es la página activa. Muy similar a la anterior.

  • ionViewWillLeave: Se ejecuta cuando sales de una página, justo antes de salir. Utilízalo para esa lógica que necesitas siempre que sales de la vista (desactivar listeners, etc).

  • ionViewDidLeave: Se ejecuta cuando sales de una página, al acabar de salir. Ahora ésta ya no es la página activa. Muy similar a la anterior.

  • ionViewWillUnload: Se ejecuta cuando vas a destruir por completo una página (al hacer pop).

Nav guards

Como bonus track hay 2 métodos muy potentes relacionados con estos eventos, que te facilitan el control de acceso a vistas que necesitan autenticación (por ejemplo).

  • ionViewCanEnter: Se ejecuta antes de entrar en una vista y te permite controlar si realmente puedes entrar en la vista o no (devolviendo true o false).

  • ionViewCanLeave: Se ejecuta antes de salir de una vista y te permite controlar si realmente puedes salir de la vista o no.

Es importante destacar que los Nav Guards se ejecutan los primeros, antes que cualquier función del lifecycle event.

Hands-on code!

Reproductor de musica ambiental

Todo se entiende mejor al ponerlo en práctica, así que te traigo un ejemplo divertido: Un reproductor de música ambiental.

Puedes bajarte el proyecto desde el siguiente enlace:

Es un ejemplo muy simple donde hay una app con 3 vistas:

  • La vista Home permite escoger un ambiente sonoro
  • La vista Music reproduce audio ligado a ese ambiente. Ya te avanzo que aquí es donde necesitarás usar los lifecycle events.
  • La vista Credits, a la que se accede desde Music, muestra información de la app

Es decir, el flujo de navegación de las vistas es el siguiente:

Relax Yourself Lifecycle

La vista Music reproducirá música según el ambiente seleccionado. La reproducción de música corre a cargo de howler.js.

Vista Home

La vista principal es muy simple: Muestra una lista de botones para acceder a los distintos ambientes, con una imagen de fondo y un texto. Todo esto aderezado con un poquito de SaSS para ponerlo bonito.

Relax yourself

 
El template de esta vista no tiene nada especial, solo destacar que para pasar a cada ambiente se llama al método goToMusicPage() del propio componente, pasando como argumento el nombre del ambiente.

home.html

<ion-header>
  <ion-navbar>
    <ion-title>Relax yourself v0.1</ion-title>
  </ion-navbar>
</ion-header>


<ion-content>

  <div class="imageBtn" (click)="goToMusicPage('ocean-waves')">
    <div class="image" style="background-image:url('assets/img/ocean-waves.jpg');"></div>
    <div class="label">Ocean Waves</div>
  </div>

  <!-- ...some more DIVs like this ...-->

</ion-content>

 
Puedes ver la navegación que hace goToMusicPage en el código del componente:

home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { MusicPage } from '../music/music';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {}

  goToMusicPage(audio){
    this.navCtrl.push(MusicPage, {audio});
  }

}

Vista Music

La vista Music es aún más simple. Solo muestra una imagen relacionada con el ambiente y un botón en el header para ir a la vista Credits.

Eso sí, en esta vista oyes música.

relaxing ocean waves

 
Lo único destacable del template de Music es la navegación a Credits con la directiva navPush.

music.html

<ion-header>
  <ion-navbar>
    <ion-title>Playing...</ion-title>

    <ion-buttons end>
      <button ion-button icon-only [navPush]="creditsPage">
        <ion-icon name="information-circle"></ion-icon>
      </button>
    </ion-buttons>

  </ion-navbar>
</ion-header>

<ion-content>
  <div [style.backgroundImage]="'url(' + image +')'"></div>
</ion-content>

 

Si no reprodujera audio, el componente Music sería muy simple:

music.ts

import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { CreditsPage } from '../credits/credits';
import * as howler from 'howler';


@Component({
  selector: 'page-music',
  templateUrl: 'music.html'
})
export class MusicPage {

  music:any;
  image:string;
  creditsPage:any;

  constructor(public navCtrl: NavController, public params: NavParams) {
    this.creditsPage = CreditsPage;
  }

  /* lifecycle events */
  //TODO: add lifecycle events to load, play, pause and stop audio
  /* end lifecycle events */ 
}

Pero como ves, necesito usar los eventos de lifecycle para gestionar la carga y reproducción del audio.

ionViewDidLoad

Cuando cargo un ambiente musical (push), necesito meter en memoria el audio correspondiente, pero sin hacerlo varias veces. Por eso utilizo ionViewDidLoad.

Como ves recibo el nombre del ambiente por parámetro y lo uso para obtener la imagen de fondo y cargar el audio correspondiente.

export class MusicPage {
  /* ...some stuff ...*/


  /* lifecycle events */

  ionViewDidLoad() {
    let audioFile = this.params.get('audio');
    this.music = new howler.Howl({ src: [`assets/music/${audioFile}.mp3`]});
    this.image = `assets/img/${audioFile}.jpg`;
  }  

  //TODO: add lifecycle events to play, pause and stop audio
  /* end lifecycle events */ 
}

ionViewWillEnter

Cada vez que Music pasa a ser la vista activa hay que reproducir su audio ambiente. Esto lo hago en ionViewWillEnter porque si lo hiciera en el evento anterior, no se ejecutaría al volver de la vista Credits.

Nota: ionViewWillLeave también serviría)

export class MusicPage {
  /* ...some stuff ...*/

  /* lifecycle events */
  ionViewDidLoad() {/*...*/}  

  ionViewWillEnter(){
    this.music.play();
    this.music.loop(true);
  }

  //TODO: add lifecycle events to pause and stop audio
  /* end lifecycle events */ 
}

ionViewDidLeave

Cada vez que Music deja de ser la vista activa hay que pausar su audio ambiente. Uso ionViewDidLeave para que funcione también al navegar a Credits.

Nota: ionViewWillLeave también serviría.

export class MusicPage {
  /* ...some stuff ...*/

  /* lifecycle events */
  ionViewDidLoad() {/*...*/}
  ionViewWillEnter() {/*...*/}

  ionViewDidLeave(){
    this.music.pause();
  }

  //TODO: add lifecycle events to stop audio
  /* end lifecycle events */ 
}

ionViewWillUnload

Finalmente, quiero asegurarme de que al volver a Home, antes de destruir la vista Music he parado la música. Para eso utilizo ionViewWillUnload.

export class MusicPage {
  /* ...some stuff ...*/

  /* lifecycle events */
  ionViewDidLoad() {/*...*/}
  ionViewWillEnter() {/*...*/}
  ionViewDidLeave() {/*...*/}

  ionViewWillUnload() {
    this.music.stop();
    this.music = null;
  } 

  /* end lifecycle events */ 
}

Vista Credits

La vista Credits es solo una excusa para mostrarte la utilidad de los eventos anteriores. Es tan simple que no te enseño ni el código, con una captura bastará 😉

credits view

Resultados

Aquí tienes un vídeo con el resultado. Acuérdate de subir el sonido, sino no tiene gracia 😉

Si tienes alguna duda o comentario, házmelo saber aquí abajo 😉

Published inAngular 2ionicIonic 2TypeScript

24 Comments

  1. Dani Dani

    Hola Enrique,

    Viene de perlas. Aunque cuando explicas algo, todo parece facil, happy & water-flowing.. pero cuando uno se pone… eso es otra cosa, y para mi está siendo una cruz, un paso para adelante y dos para atrás.. ;-p

    Sería genial un bonus track 2, con la navegación por tabs y cuando usar viewChild (que no me aclaro) y la diferencia entre Nav y NavController ,y… Como usar servicios en un modal ¿se puede? y… (lo se, solo hago que pedir .. .. )

    merci !

    • Enrique Oriol Enrique Oriol

      Tomo nota 😉

      ¿Qué cosas te han presentado dificultades de este tutorial en concreto?

      ¡Un abrazo!

  2. Pablo Ramos Pablo Ramos

    Hola!

    Tengo una consulta. Me bajé el proyecto, le di npm install, luego ionic serve, todo funciono bien en el navegador de escritorio. Queria probarlo en el movil, así que le di ionic upload para verlo con ionic view, y veo unos problemas:

    1. La música se escucha entrecortada
    2. Cuando vuelves al home se sigue escuchando.

    Es un problema puntual mío? o alguien también le pasa.

    Gracias!!

    • Enrique Oriol Enrique Oriol

      Yo lo he ejecutado en dispositivo Android sin problemas.

      ¿Has probado a debugar para ver por qué no se para al volver a home? Lo de la música entrecortada podría deberse al dispositivo. ¿Qué móvil es?

      Saludos

      • Pablo Ramos Pablo Ramos

        Lo has ejecutado con ionic view? voy a debugar para ver si encuentro algo. Es un samsung galaxy alpha android 4.4.4

      • Enrique Oriol Enrique Oriol

        No, yo ejecuto directamente sobre el dispositivo, asi te evitas pelear con problemas que pueden no venir de tu código.

  3. recursospremiumwpAlfredo recursospremiumwpAlfredo

    un video tutorial de esto no seria mala idea 😀 se entiende todo mejor cuando lo explicas paso por paso

  4. Excelente explicación! , tengo una duda es posible comunicar aplicaciones entre si con Ionic 2 ? Es decir pasar un valor cualquiera de una aplicación “A” a otra aplicación aparte “B” , es posible

    • Enrique Oriol Enrique Oriol

      Pues así como así no, pero puedes hacer que las dos apps se comuniquen con el mismo servidor o lanzar una app desde la otra a través de URLScheme y aprovechar para pasarle información.

      • Gracias por la respuesta! logre hacerlo con URLScheme.

  5. Hola Enrique!
    Muy bueno y sencillo el tutorial, solo quisiera hacerte una pregunta.

    Que diferencia hay entre usar Howler.js y el audio nativo de HTML5? Por lo que veo, los metodos de estos son bastantes parecidos (audio.play() , audio.pause(), etc)

    Pregunto porque primero se me ocurrio hacerlo con html5, lo hice y funcionó. Pero despues quise investigar un poco a ver si habia alguna manera “mejor” de hacerlo.
    Por ejemplo, al bloquear pantalla, usando el reproductor de html5, se para el audio. Y en moviles esto es algo basico que no tiene que pasar para una app musical.

    Saludos!

    • Enrique Oriol Enrique Oriol

      Howler.JS utiliza la Web Audio API y en caso de incompatibilidad, acaba usando la API de audio de HTML5. Si te paras a mirar lo que se puede hacer con Howler.JS, verás que es mucho más potente que la API de audio de HTML5.

      En todo caso, para un ejemplo tan simple como este, he elegido HowlerJS por una cuestión de gustos: No me gusta que el audio vaya metido en una etiqueta HTML, así de fácil 😉

      • Perfecto, es Io que necesitaba saber. Una ultima pregunta… para incluir Howler.JS en el proyecto, como hago?

      • Enrique Oriol Enrique Oriol

        Para instalarlo, desde terminal:

        npm install howler

        Y donde lo quieras usar lo importas con sintaxis ES6:

        import * as howler from 'howler';

        Si tienes dudas puedes mirar el código del repo: https://github.com/kaikcreator/ionic2LifeCycleExample

      • Genial, muchísimas gracias! También me sirvió mucho el post de celery + django.

        Un saludo y gracias por compartir estas cosas!

      • Enrique Oriol Enrique Oriol

        Me alegro de que te sirva 😉

        ¡Saludos!

    • Enrique Oriol Enrique Oriol

      Si claro, ¿por qué no?

  6. Hola, me parece muy buento tu post y te lo agradezco por que es de mucha ayuda, pero una consulta. Al compilar me arroja un error linea de let audioFile = this.params.get(‘audio’);. El error dice: No platforms add.Please use cordova platform add

    • Enrique Oriol Enrique Oriol

      Ese error básicamente te indica que tienes que añadir una plataforma cordova (android o ios). Eso será por que estás haciendo un `build` o un `run` y claro, necesitas tener los archivos de cordova instalados para crear la app.

  7. Walter Ramos Walter Ramos

    Intenté creando uno nuevo o utilizando lo que dejaste en el repositorio, pero no me funciona. No me carga las imágenes, tampoco se escucha los audios =(. Lo compilé y probé en mi móvil.
    No sé si sea por las versiones o algo. Ayuda por favor.

  8. Fernando Fernando

    Hola, gracias por compartir.

    Podrias hacer un tutorial explicando como cargar las canciones del almacenamiento del movil con ionic 3

  9. Cuando uso un proyecto con SideMenu cada que navego entre las distintas pagina se me llama todo lo que está en ionViewDidLoad de la pagina funcionando como si fuera un ionViewDidEnter.
    Como puedo solucionarlo?

  10. Hola Enrique Oriol, gracias por este tutorial y por todo tu aporte que haces a la comunidad, tengo una consulta. estoy realizando una aplicación en donde quiero reproducir audio streaming, veo que ionic tiene un plugin de Streaming Media pero al momento de pasar a otra vista o el telefono se bloquea la aplicacion deja de sonar.
    howler permite trabajar audio streaming? y ademas permite trabajar en background mode?

    podrias tal vez hacer una actualizacion de este temas abordando el punto de audio streaming y el trabajo en backgroun mode?

Deja un comentario