Después de unos días desconectado por vacaciones y preparando también alguna sorpresilla… vuelvo a la carga para responder a la duda de uno de vosotros: ¿Como funcionan las rutas en Ionic 2?
Navegación «nativa»
Supongo que aprendiendo de la experiencia, el equipo de Ionic ha pasado olímpicamente del router de Angular 2 (que por cierto, no ha parado de cambiar desde que lanzaron su primera versión), y ha creado su propio sistema basándose en la navegación nativa de iOS para que la navegación en Ionic 2 sea lo más natural posible.
Esto quiere decir que la navegación está menos orientada a usar URLs (aunque se puede) como en las webs tradicionales, y más orientada al tipo de navegación que se hace desde un móvil, donde es habitual moverse adelante y atrás, o pasar de repente a una sección completamente distinta.
Stack de vistas
El concepto básico de la navegación con Ionic 2 es la pila de vistas (o stack).
Esto es básicamente que vamos apilando las vistas, una encima de otra, cada vez que pasamos a la siguiente vista (hacemos push de la nueva vista), y las quitamos de la pila cuando volvemos atrás (hacemos pop de la vista que queremos quitar) .
Navegación básica
Pongamos como ejemplo la siguiente aplicación inmobiliaria para buscar pisos:
- La vista principal muestra un listado de ciudades
- Al seleccionar la ciudad, se muestra un listado de distritos
- Al seleccionar distrito, la app te lleva a una vista con el listado de pisos de ese distrito
- Al seleccionar un piso, te lleva a la vista de detalle con información del piso
El nuevo sistema de rutas de Ionic 2 te facilita una navegación muy natural:
- En cada selección, se hace push de la vista siguiente
- Si en algún momento, seleccionas el botón atrás, se hace un pop de la vista actual.
Con la animación siguiente lo entenderás de un plumazo.
Vista root
El otro concepto importante es la vista raíz, es decir, la que funciona como base de la pila. En el ejemplo anterior, la vista raíz es la vista «Cities».
Además de poder hacer push/pop de vistas, podemos cambiar también la vista raíz y reiniciar así la pila de vistas tomando como base la nueva vista que hemos asignado como root.
Puedes reiniciar la pila de vistas cambiando directamente la vista raíz.
Si en el ejemplo anterior tuviéramos un menú lateral con la opción de settings y la seleccionamos, este cambio de vista sería claramente una situación en la que nos interesaría cambiar la raíz en lugar de hacer un push de la vista, ya que es un cambio de contexto (la vista de configuración de una app no tiene nada que ver con que estés viendo un listado de apartamentos).
Tabs
Los tabs de Ionic 2 es un caso particular de navegación, ya que en realidad, cada tab esconde su propia pila de vistas, de modo de cuando cambias de tab, lo que haces es cambiar de pila. Esto también es un comportamiento copiado de las aplicaciones iOS, y tiene todo el sentido del mundo.
Quizá si vienes de web no te parece una forma muy lógica de gestionar la navegación entre vistas, pero se adapta perfectamente al comportamiento de navegación en cualquier aplicación móvil.
Hands on code
Está muy bien esto de la teoría, pero te preguntarás… bueno, vale, ¿cómo se hace esto en realidad?
Ion-nav
El componente básico de navegación en Ionic 2 es el <ion-nav>
.
En la vista en la que quieres empezar a tener navegación (normalmente el componente App), debes incluir este componente en el template y pasarle una referencia a la vista que quieres que cargue como raíz.
Esto lo harás con un property binding a la propiedad root
de este componente.
Por ejemplo, si quieres que el sistema de navegación cargue por defecto la vista StartPage
, tienes que hacer esto:
//app.ts
import {StartPage} from 'start'
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
class MyApp {
// First page to push onto the stack
rootPage = StartPage;
}
Como ves, en el componente MyApp
declaro una propiedad rootPage
a la que le asigno el componente StartPage
que quiero cargar por defecto. Entonces, en su template, asigno la variable rootPage
a la propiedad root
del <ion-nav>
.
push/pop (NavController)
Para hacer push/pop de vistas, necesitas inyectar el servicio NavController
de Ionic 2.
Pongamos por ejemplo que estás en la vista StartPage
que se ha cargado antes y quieres pasar a la vista SecondPage
al hacer click en un botón.
Tu vista StartPage
necesitará acceder al servicio NavController
para llamar a su método PUSH, además de importar la vista SecondPage
para pasarla como argumento.
Tu vista tendría un aspecto similar a este:
//start-page/start-page.ts
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import { SecondPage } from 'second-page/second-page';
@Component({
template: `
<ion-content>
<button (click)="goToSecondPage()">
Go to SecondPage
</button>
</ion-content>`
})
export class StartPage {
constructor(public navCtrl: NavController) {}
goToSecondPage() {
this.navCtrl.push(SecondPage);
}
}
¿Que quieres volver atrás desde SecondPage
? Fácil, solo necesitas inyectar el servicio NavController
y llamar al método POP:
//second-page/second-page.ts
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
@Component({
template: `
<ion-content>
<button (click)="goBack()">
Go back!
</button>
</ion-content>`
})
export class SecondPage {
constructor(public navCtrl: NavController) {}
goBack() {
this.navCtrl.pop();
}
}
Tabs
Como decía, el uso de tabs es un caso particular, en el que cada tab tiene su propio stack de navegación, a partir del cual se puede navegar como siempre con el servicio NavController
.
La diferencia principal se encuentra en el template de la vista principal donde quieres meter la navegación, ya que en lugar de usar un <ion-view>
usarás los componentes <ion-tabs>
y <ion-tab>
.
Veamos un ejemplo:
//myApp.ts
import { Component } from '@angular/core';
import { Tab1 } from './tab1-page';
import { Tab2 } from './tab2-page';
@Component({
template: `
<ion-tabs>
<ion-tab tabIcon="heart" [root]="tab1"></ion-tab>
<ion-tab tabIcon="star" [root]="tab2"></ion-tab>
</ion-tabs>`
})
class MyApp {
tab1: any;
tab2: any;
constructor() {
this.tab1 = Tab1;
this.tab2 = Tab2;
}
}
En el ejemplo puedes ver como el template incluye 2 tabs, donde cada uno tiene su propia root view.
La gracia del componente <ion-tab>
es que el solito es capaz de detectar el click y llevar a cabo el cambio de pila de navegación.
Luego, una vez te encuentras dentro de Tab1 o Tab2, lo único que tienes que hacer es usar NavController
como siempre para navegar dentro de su stack con push y pop.
Conclusiones
Espero que este artículo te haya aclarado el mecanismo de navegación de Ionic 2.
Como conclusiones, te diré (quizás con un punto de vista sesgado por haber trabajado bastante con iOS en el pasado) que me parece una aproximación muy acertada a las necesidades del usuario mobile.
¿Y a ti, te parece acertado? Yo personalmente creo que te va a facilitar el paso de unas vistas a otras mucho más que el sistema ui-router que usaba su predecesor, Ionic 1.
Tiempo al tiempo.