Tutorial de Ionic – Crear una aplicación para guardar nuestros sitios geolocalizados – Parte 1 – Navegación por Tabs

En el siguiente enlace tienes el índice para acceder al resto de entradas de este tutorial:

 

¡¡Atención!! este tutorial se basa en ionic 3 y está desactualizado por lo que es posible que los ejemplos no funcionen en la última versión de ionic, haz click aquí para acceder a un tutorial mas actual de Ionic.

Hola a todos.

En el capítulo anterior de este tutorial sobre Ionic 2 creamos una app simple, un minijuego de adivinar números que nos sirvió para prender cómo se programa la lógica de una página en Ionic 2.

Vimos cómo pasar variables entre el controlador de la página y la vista y cómo llamar a funciones desde un evento de la vista como pulsar un botón.

La aplicación era extremadamente sencilla y toda la lógica se desarrollaba en la misma página, sin embargo lo normal en cualquier aplicación que sea mínimamente completa es que tenga varias vistas o páginas y haya que navegar entre ellas.

Hoy vamos a aprender a hacer una aplicación con varias páginas y veremos cómo podemos navegar entre ellas, para ello vamos a realizar una aplicación de ejemplo.

Descripción de la aplicación:

La aplicación consistirá en una herramienta que nos permita guardar el lugar donde nos encontramos actualmente recogiendo las coordenadas gracias al gps del móvil.

Está aplicación puede sernos útil por ejemplo para recordar donde hemos aparcado el coche o para guardar un restaurante que nos ha gustado y queremos volver más tarde etc.

La aplicación constará de una pantalla inicial con un mapa donde se mostrará la posición actual y un botón para añadir la posición actual. Al pulsar el botón se abrirá una ventana modal con un pequeño formulario donde añadir una descripción y un fotografía.

Los lugares que guardemos se mostrarán en otra página que contendrá un listado de tus sitios guardados.

Al pinchar sobre uno de nuestros sitios guardados se abrirá otra ventana modal donde mostraremos la foto, la dirección y la descripción del mismo.

Bien, vamos a comenzar creando nuestra aplicación. Desde la consola de comandos o terminal escribimos:

ionic start misSitios blank

Una vez creada nuestro proyecto vemos que por defecto nos ha generado la página home dentro de la carpeta pages.

Nosotros a priori vamos a utilizar tres páginas, una con el mapa donde se muestra nuestra posición actual, otra con el listado de nuestros sitios guardados y otra que llamaremos info donde mostraremos información sobre la aplicación y que simplemente utilizaremos de relleno para tener una tercera página y poder mostrar mejor como funciona la navegación entre páginas.

Las paginas normalmente suelen estar asociadas a “tabs” o pestañas y se navega entre ellas cambiando de tab.

Ionic Generator

Nosotros podemos crear las páginas a mano creando una carpeta dentro de la carpeta pages con su vista html y su controlador .ts, y su css, también podemos crear y configurar los tabs a mano, pero el cli (command line interface o interfaz de linea de comandos) de ionic nos facilita muchísimo el trabajo. Ionic dispone de una herramienta llamada ionic generator.

Ionic generator nos permite generar plantillas con los componentes que queramos.

Con el siguiente comando obtenemos la lista de elementos disponible que podemos generar con ionic generator:

ionic g --list

Recordad que debemos estar dentro de la carpeta del proyecto para poder ejecutar cualquier comando de ionic, por lo que deberemos escribir cd misSitios desde consola para entrar dentro de la carpeta de nuestro proyecto.

La lista de elements que podemos generar automáticamente con ionic generator son:

  • Component: Los componentes son un conjunto de html, con su css y su comportamiento que podemos reutilizar en cualquier lugar sin tener que reescribir de nuevo todo.
  • Directive:
    Una directiva sirve para modificar atributos de un elemento.
  • Page: Páginas.
  • Pipe: Los pipes son lo que angular 1 se consideraban filtros.
  • Provider:Los providers son proveedores que se encargan del manejo de datos, bien extraídos de la base de datos, desde una api, etc.
  • Tabs: Nos genera la página maestra de Tabs y una página para cada tab.

Veremos con más detalle cada elemento según lo vayamos necesitando, para este ejemplo de momento nos interesan los Tabs.

Seleccionamos Tabs y como  nombre le ponemos misTabs, también podemos generar directamente los tabs con el siguiente comando:

ionic g tabs misTabs

Al ejecutar el comando primero nos pregunta el número de tabs que queremos crear, para este ejemplo vamos a utilizar 3.Utilizamos la flecha hacia abajo del cursor para seleccionar el tres y pulsamos enter.

Acto seguido debemos introducir el nombre del primer tab: le damos el nombre de Inicio y pulsamos enter.

Después nos pide que introduzcamos el nombre para el segundo Tab: A este tab le vamos a llamar Listado.

Pulsamos enter una vez mas y por ultimo introducimos el nombre del tercer tab. Le llamamos Info y pulsamos enter.

captura ionic generator tabs

Hay que tener cuidado al utilizar el comando ionic g tabs porque si alguna de las páginas que creamos con ionic g tabs ya existe la “machaca” y la crea de nuevo vacía.

Si echamos un vistazo a las carpetas de nuestro proyecto vemos que en la carpeta /src/pages se han creado cuatro páginas nuevas, una por cada uno de los tabs que acabamos de crear y una cuarta llamada mis-tabs que sera la página maestra de los tabs.

 

captura-de-pantalla-2017-01-28-a-las-15-57-22

Desde la versión 3 de ionic al crear una página con ionic generator además del archivo nombre_pagina.ts también se genera un archivo nombre_pagina.module.ts en cada página generada, este archivo se utiliza para poder realizar lo que se conoce como Lazy Loading, que permite cargar paginas y recursos bajo demanda acelerando así la carga de las páginas.

Esta nueva característica es opcional, si no queremos utilizarla, para que no de error deberiamos eliminar el archivo xxx.module.ts de todas las páginas.

Para poder realizar lazy loading necesitamos importar IonicPage junto con NavController de ionic-angular e incluir el decorador @IonicPage() en cada página. El decorador @IonicPage() nos permite definir los deep links directamente en el componente, esto lo hace automáticamente ionic generator al crear una página.

Como a partir de ahora vamos a utilizar lazy loading, si ionic generator no lo genera automáticamente, tendremos que crear estos elementos a mano.

Si abrimos el archivo mis-tabs.module.ts vemos que tiene el siguiente  código:

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { MisTabsPage } from './mis-tabs';

@NgModule({
  declarations: [
    MisTabsPage,
  ],
  imports: [
    IonicPageModule.forChild(MisTabsPage),
  ],
  exports: [
    MisTabsPage
  ]
})
export class MisTabsPageModule {}

Como vemos  importa NgModule, IonicPageModule y la propia página, en este caso MisTabsPage, después en @NgModule se declara MisTabsPage en declarations, en  imports con IonicPageModule.forchild(MisTabsPage) y en exports.

Si abrimos el archivo mis-tabs.ts dentro de carpeta mis tabs vemos el siguiente código:

import { Component } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';

/**
 * Generated class for the MisTabsPage tabs.
 *
 * See https://angular.io/docs/ts/latest/guide/dependency-injection.html for
 * more info on providers and Angular DI.
 */
@Component({
  selector: 'page-mis-tabs',
  templateUrl: 'mis-tabs.html'
})
@IonicPage()
export class MisTabsPage {

  inicioRoot = 'InicioPage'
  listadoRoot = 'ListadoPage'
  infoRoot = 'InfoPage'


  constructor(public navCtrl: NavController) {}

}

Esta es la pagina maestra donde vamos a controlar la navegación por tabs.

Vemos que ha creado una variable para cada tab (inicioRoot,listadoRoot, e infoRoot) y les ha asignado el controlador de una página a cada uno entre comillas (‘). Al realizar Lazy loading no necesitamos importar las páginas ni declararlas en app.module.ts, simplemente se declaran en su propio archivo de modulo y se hace referencia con el nombre de la clase como string, por eso hay que ponerlo entre comillas.

Bien, si ejecutamos ionic seve -l para ver e resultado ahora nos muestra la página home que se crea por defecto al crear un proyecto ionic vacío, tenemos que indicarle a la aplicación que la página inicial debe ser la página maestra con los tabs que acabamos de crear.

Cambiar el root de nuestra aplicación (Página principal)

Para indicarle a la aplicación que la página principal sea la página maestra de los tabs que acabamos de crear debemos editar el archivo src/app/app.component.ts e importar la pagina MisTabsPage con import y luego a la variable rootPage asignarle el nombre de la clase de la página que queremos asignar como página principal, en este caso MisTabsPage.

Dado que nuestro componente MisTabsPage está ahora cargado utilizando lazy loaded, no queremos importarlo directamente y hacer referencia a él en cualquier lugar. En su lugar, podemos pasar una cadena que coincida con el componente por lo tanto debemos asignar a rootPage la cadena ‘MisTabsPage’ entre comillas, es decir debemos sustituir:

rootPage = HomePage;

Por:

rootPage = 'MisTabsPage';

El código del archivo src/app/app.component.ts completo quedaría así:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage = 'MisTabsPage';

  constructor(platform: Platform) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();
    });
  }
}

El import de la página home ya no lo necesitamos así que podemos eliminarlo. De hecho podemos eliminar la carpeta de la pagina home ya que no la vamos a utilizar en esta aplicación, eso sí, antes de borrar la carpeta de la página home elimina también el import y las declaraciones de homePage en el archivo app.module.ts.

El archivo app.component.ts es el punto de entrada de nuestra aplicación, vemos que se define como un componente que utiliza como plantilla el archivo app.html.

@Component({
  templateUrl: 'app.html'
})

Si vemos el contenido de app.html podemos observar que únicamente contiene la siguiente linea de código:

<ion-nav [root]="rootPage"></ion-nav>

Le asigna como root (es decir como página inicial o raíz) la variable rootPage, y como a la variable rootPage le hemos asignado la página MisTabsPage, la aplicación cargará dentro de <ion-nav> el contenido de la página MisTabsPage.

De momento no necesitamos modificar nada mas en app.component.ts, solo comentar que por defecto se importa el elemento platform que tiene el método ready que podemos utilizar para ejecutar acciones que queremos que se produzcan en el momento que la aplicación esté completamente cargada:

platform.ready().then(() => { ... }

De momento lo dejamos como está.

Ahora ya podemos ejecutar nuestra aplicación y ver las tres pestañas que nos ha creado:

Nuestra app con tabs
Nuestra app con tabs

Como vemos ha creado por defecto un icono para cada pestaña.

Vamos a ver como podemos cambiar los iconos de los tabs para ello vamos ahora a ver el contenido de la plantilla mis-tabs.html:

<ion-tabs>
    <ion-tab [root]="inicioRoot" tabTitle="Inicio" tabIcon="information-circle"></ion-tab>
    <ion-tab [root]="listadoRoot" tabTitle="Listado" tabIcon="information-circle"></ion-tab>
    <ion-tab [root]="infoRoot" tabTitle="Info" tabIcon="information-circle"></ion-tab>
</ion-tabs>

Como podemos observar la página maestra de los tabs (mis-tabs.html) solamente contiene el contenedor de tabs que se define con la etiqueta <ion-tabs> y luego una etiqueta <ion-tab> por cada tab. También podemos observar que cada tab tiene el atributo [root] donde se le asigna la variable que indica la pagina que se debe mostrar en cada tab.

Luego tenemos el atributo tabTitle al que se le asigna el texto que se muestra en el tab, si solo queremos que se muestre el icono podemos eliminar o dejar vacío este atributo.

Y por último tenemos el atributo tabIcon y es aquí donde se le asigna el icono que se muestra en cada tab, si solo queremos que se muestre texto podemos eliminar o dejar vacío este atributo.
Si corres la aplicación en el navegador con ionic serve -l puedes observar que en iOS los iconos son diferentes a los iconos de Android. Los iconos cambian dependiendo de la plataforma móvil adaptandose al estilo propio de la plataforma. Esta es una de las ventajas de ionic a partir de la versión 2, que no te tienes que preocupar por adaptar el estilo que tu app para cada plataforma ya que la mayoría los elementos se adaptan automáticamente al estilo propio de cada sistema.

Probablemente te estarás preguntando, pero…¿de donde salen estos iconos?.La respuesta es simple, ionic viene de serie con una colección de los iconos mas comunes lista para ser usada solamente con asignar como hemos visto el nombre del icono al atributo tabIcon.

El listado de iconos disponibles lo podéis consultar el la documentación oficial de ionic desde el siguiente enlace: https://ionicframework.com/docs/ionicons/

El tab Inicio lo vamos a dejar con el icono home, al tab Listado le vamos a asignar el icono list-box y al tab Info le vamos a asignar el icono information-circle:

<ion-tabs>
  <ion-tab [root]="inicioRoot" tabTitle="Inicio" tabIcon="home"></ion-tab>
  <ion-tab [root]="listadoRoot" tabTitle="Listado" tabIcon="list-box"></ion-tab>
  <ion-tab [root]="infoRoot" tabTitle="Info" tabIcon="information-circle"></ion-tab>
</ion-tabs>

Para observar mejor como cambiamos entre las distintas páginas de momento vamos a poner un comentario en cada una.

Editamos inicio.html y dentro de ion-content añadimos lo siguiente:

<!--
  Generated template for the Inicio page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar>
    <ion-title>Inicio</ion-title>
  </ion-navbar>

</ion-header>


<ion-content padding>
  <h1>Esta es lá página de inicio, aquí situaremos un mapa con un botón de añadir lugar.</h1>
</ion-content>

Editamos listado.html y añadimos los siguiente:

<!--
  Generated template for the Listado page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar>
    <ion-title>Listado</ion-title>
  </ion-navbar>

</ion-header>


<ion-content padding>
  <h1>Aquí estará el listado de sitios guardados.</h1>
</ion-content>

Y por último editamos info.html dejándolo de la siguiente manera:

<!--
  Generated template for the Info page.

  See http://ionicframework.com/docs/v2/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar>
    <ion-title>Info</ion-title>
  </ion-navbar>

</ion-header>


<ion-content padding>
<h1>Mis sitios:</h1>
<p>Aplicación de muestra del Tutorial de Ionic 2 – Construye Apps móviles multiplataforma con ionic 2 desde cero.</p>
</ion-content>

Ahora al navegar por las pestañas podemos ver algo parecido a esto:

Nuestras tres pestañas en funcionamiento-.
Nuestras tres pestañas en funcionamiento.

Como no quiero hacer posts demasiado largos de momento lo dejamos aquí. Hoy hemos aprendido a crear una aplicación con tabs para navegar entre diferentes paginas usando el comando ionic g tabs.

En el próximo post seguiremos creando nuestra aplicación para guardar sitios. Insertaremos un mapa en la página de inicio y capturaremos las coordenadas actuales.

 

Si necesitas desarrollar una aplicación móvil no dudes en solicitarme un presupuesto sin compromiso:

Un saludo, y si aún no lo has hecho no olvides suscribirte a mi blog para no perderte los próximos posts  :-),

También puedes seguirme en Twitter en ‎@revigames y no olvides que me ayudas mucho si compartes este post en las redes sociales.

25 comentarios en “Tutorial de Ionic – Crear una aplicación para guardar nuestros sitios geolocalizados – Parte 1 – Navegación por Tabs

    1. Gracias por el apoyo y por la paciencia, desafortunadamente dispongo de muy poco tiempo para escribir en el blog y muchas veces se demora demasiado la publicación de un nuevo post. Se agradece mucho el apoyo.

      Un saludo

  1. Hola Eduardo… No quería molestarte con esto, pero ya es 4 vez que sigo el tutorial al pie de la letra y me sale el mismo error.
    Todo va bien hasta el momento de ejecutar la aplicación para ver las tabs que hemos creado. Me sale un error con respecto a la clase myApp. Al final, en el último intento, borre la carpeta home de pages, y el error a cambiado: Module build failed: Error: ENOENT: no such file or directory, open ‘C:IonicmisSitiossrcpageshomehome.ts’ at Error (native)

    Entiendo el error, pero no entiendo por que aparece. He revisado mis archivos y ya nada hace referencia a la home page… no se que pueda estar pasando. Slds

    1. Hola Dc, como no especificas que error te daba al principio sobre la clase myApp no puedo saber que te está fallando, en cualquier caso revisa el archivo app.component.ts y asegúrate que está exactamente igual que muestro en el post.
      En cuanto al error que te sale ahora después de borrar la carpeta home es por que en algún sitio sigues haciendo referencia a ella en algún import, revisa app.component.ts y app.module.ts y comprueba que no haya ninguna referencia a home.

      Un saludo

      1. Ms disculpas Eduardo, al parecer he tipeado algo mal, al final he copiado y pegado tal cual tu código, y ha funcionado correctamente. A seguir con los tutoriales, y muchas gracias por lo que haces 🙂

  2. Muy bien explicado espero y siga haciendo mas tutoriales como estos ya que son de mucha utilidad , de hecho estoy trabajando con un proyecto asi en ionic y me serviría si se diera el tiempo de explicar sobre mas funciones que tiene ahora ionic 2 como el uso de componenete, directivas y modulos ya que es un poco diferente al 1, de cualquier forma muchas gracias!

  3. De todos los tutoriales de ionic que he encontrado en inglés y español, este ha sido el más completo, actualizado y mejor explicado.
    Muchas gracias

  4. Hola, me ha gustado harto el tutorial pero quería ver si me podrían ayudar por favor. Lo que pasa es que la app no me crean los archivos .module.ts respectivo en cada tab, por lo cual no puedo editar eso. Me pregunto si tiene que ver con que al crear las tabs, si se crean pero al final de la consola da el error “TypeError: Cannot read property ‘replace’ of undefined” . Ayuda por favor.
    Gracias de antemano

    1. pd mi pp.component.ts es algo distinto también.. No sé si estaré usando una versión distinta (aún soy nuevo en esto..)

      export class MyApp {
      rootPage:any = MisTabsPage;

      constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
      platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
      });
      }
      }

      1. Saludos tu error esta en que haces referencia a la pagina MisTabsPages sin las comillas simples, es por eso que no encuentra la pagina raiz para cargar los tabs; El codigo debe verse como el siguiente:

        import { Component } from ‘@angular/core’;
        import { Platform } from ‘ionic-angular’;
        import { StatusBar } from ‘@ionic-native/status-bar’;
        import { SplashScreen } from ‘@ionic-native/splash-screen’;
        //import { HomePage } from ‘../pages/home/home’;

        @Component({
        templateUrl: ‘app.html’
        })
        export class MyApp {
        rootPage:any = ‘MisTabsPage’;

        constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
        //El metodo platform tiene como metodo ready que es utilizado, para ejecutar acciones que querramos en el momento que la app se carga por completo

        platform.ready().then(() => {
        // Okay, so the platform is ready and our plugins are available.
        // Here you can do any higher level native things you might need.
        statusBar.styleDefault();
        splashScreen.hide();
        });
        }
        }

    2. Hola Alexis, por lo visto es un problema con la ultima versión de ionic, en cuanto a no generar los archivos .module.ts se debe a que en la version 3.5.2 el comportamiento de ionic g ha cambiado y ya no se generan automáticamente los archivos .module.ts para hacer lazy loading.
      Han dicho que en próximas versiones volverán a incluirlo, habrá que estar atentos.
      Ahora para poder utilizar lazy loading hay que crear estos archivos a mano.
      Otra opción es volver a una versión anterior de ionic con npm install -g ionic@3… “Los puntos suspensivos seria el numero de version al que quieres volver”.
      Por último podemos no utilizar lazy loading, para ello debemos importar y declarar todas las paginas en app.module.ts, e importarlas también donde vayamos a utilizarlas.
      La verdad es que eso de que con cada versión cambien el modo de hacer las cosas resulta un poco desesperante…

      Gracias por comentar,

      Un saludo

  5. Excelente tutorial me he encontrado con error al momento de cambiar la página de inicio “error: Uncaught (in promise): invalid link: MisTabsPage”

    Ionic Framework: 3.5.3
    Ionic App Scripts: 2.0.2
    Angular Core: 4.1.3
    Angular Compiler CLI: 4.1.3
    Node: 6.11.1
    OS Platform: Windows 10
    Navigator Platform: Win32
    User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

    1. Hola Marco Antonio, este problema es debido a que en la reciente version de ionic 3.5.2 se ha desactivado la creación automática del archivo .module.ts cuando se crea una página con ionic generator.
      He modificado el tutorial explicando como generar a mano este archivo.

      Gracias por comentar.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.