Generadores de Ionic 2

Otro comando importante del CLI de Ionic, que no vimos en el primer post, es generate, el cual nos ayuda a crear páginas y servicios para la aplicación.

En este post vamos a utilizar generate para crear un ejemplo de página de inicio de sesión. Para crear el proyecto vamos a utilizar el comando start como vimos en posts anteriores, para ello ejecutamos en la consola:

ionic start --v2 ejemplo tabs

En la consola, entramos en la carpeta “ejemplo”, recien creada por el comando start, y crearemos la página donde vamos a colocar el formulario para iniciar sesión. Vamos a utilizar generate para crear la página, de la siguiente manera:

ionic generate page login

Como podemos ver, para la creación de páginas, pasamos los parámetros page y seguido el nombre de la página; una versión más corta de utilizar la letra “g” en lugar de generate:

ionic g page login

Si vamos a nuestro proyecto, podemos ver que se han creado tres archivos dentro de una nueva carpeta llamada “login” ubicada en “src/app/pages/”, los archivos son:

  • login.html: Contiene la plantilla HTML de la página.
  • login.ts: Contiene el código TypeScript de la página.
  • login.scss: Contiene los estilos (sass) de la página.

Nota: En Ionic 2 una página es un componente de Angular 2.

Si ejecutamos nuestra aplicación en este momento con ionic serve no vamos a notar ninguan diferencia aún, seguimos viendo la misma aplicación que creamos con ionic start, esto se debe a que Ionic nos generó una página sencilla pero aún no se está utilizando en ningun lugar de la aplicación, para ello vamos a realizar varios cambios.

Si le echamos un vistazo a la clase MyApp que se encuenta en “src/app/app.component.ts” la cual es el componente “principal” de nuestra aplicación, en ella se define cual es la página que se va a mostrar por defecto:


import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { TabsPage } from '../pages/tabs/tabs';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage = TabsPage;
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();
});
}
}

Como vemos en la línea 5, importamos la página TabsPage y en la línea 11 asignamos esta página a la propiedad rootPage; de esta manera estamos diciendo que TabsPage va a ser la página que se muestra por defecto cuando se ejecuta nuestar aplicación, esta página es la que define nuestros tabs.

Cambiemos esto para que sea “login” la página que se muestre por defecto, primeramente vamos a ver cómo Ionic nombró la clase que representa a la página “login”, para ello revisamos el archivo login.ts que mencionamos anteriormente y veremos que el nombre de la clase es LoginPage, ahora modificamos “src/app/app.component.ts“:


import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { LoginPage } from '../pages/login/login';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage = LoginPage;
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();
});
}
}

Acabamos de modificar las líneas 5 y 11, para importar y poner LoginPage como la página que se muestra por defecto.

Aún no terminamos, si ejecutamos ionic serve, vamos a ver el siguiente error:

factory-not-found-login
Error: No component factory found for LoginPage

Esto es porque debemos registrar la nueva página en la definición del módulo de nuestra aplicación, no vamos a entrar en detalles sobre este cambio en este post, sólo diremos que tiene que ver con Angular 2 y NgModule. Vamos a modificar el archivo “src/app/app.module.ts


import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { LoginPage } from '../pages/login/login';
@NgModule({
declarations: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage
],
providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }]
})
export class AppModule { }

view raw

app.module1.ts

hosted with ❤ by GitHub

En el código anterior importamos la página LoginPage en la línea 8 y la adicionamos a la lista de declaraciones y componentes de entrada en las líneas 17 y 29 respectivamente.

Esta vez, debemos ver la siguiente pantalla si ejecutamos ionic serve:

empty-login-page
LoginPage vacía

Muy bien, ya vemos la página donde vamos a colocar el formulario de inicio de sesión, es hora de adicionar un poco de HTML a la plantilla de LoginPage. Como ya habíamo visto, login.html contiene la plantilla HTML, vamos a modificarla con el siguiente código:


<ion-header>
<ion-navbar>
<ion-title>Inicio de sesión</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<form (ngSubmit)="iniciarSesion()" #inicioSesionForm="ngForm">
<ion-list>
<ion-item>
<ion-label stacked>Usuario</ion-label>
<ion-input type="text" name="usuario" [(ngModel)]="credenciales.usuario" required></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Contraseña</ion-label>
<ion-input type="password" name="contrasena" [(ngModel)]="credenciales.contrasena" required></ion-input>
</ion-item>
<div padding>
<button ion-button block type="submit" [disabled]="!inicioSesionForm.form.valid">Entrar</button>
</div>
</ion-list>
</form>
</ion-content>

view raw

login1.html

hosted with ❤ by GitHub

Hemos cambiado el título de la página, adicionado componentes para introducir el usuario y la contraseña y adicionado el botón para iniciar sesión, para ello utilizamos varios componentes de Ionic, noten todos las etiquetas que empiezan con “ion-“, estas son directivas de Ionic que representan componentes.

Ionic tiene una excelente documentación para aprender a utilizar sus componentes y sus API, por ejemplo échale un vistazo a la de ion-button.

Utilizamos [(ngModel)] en las etiquetas input para enlazar los valores de usuario y contraseña. El formulario está envuelto en una etiqueta form donde utilizamos (ngSubmit) para asignar la acción que se va ejecutar cuando se envíe el formulario, en este caso “iniciarSesion()”; el envío del formulario se va a ejecutar cuando se toque algún botón tipo submit que se encuentre dentro del formulario, en nuestro caso, el único botón que tenemos hasta ahora. Tambíen asignamos el el identificador “inicioSesionForm” a nuestro formulario, lo cual nos sirve para cuestiones de validaciones, como por ejemplo, deshabilitar el botón mientras que el formulario no sea válido. Todo esto no es más que Angular 2, no tiene nada que ver con Ionic por lo tanto no vamos a profundizar en ello, además hay varias maneras de implementar un formulario en Angular 2, esta es sólo una manera sencilla de hacerlo.

No vamos a ejecutar ionic serve aún porque necesitamos hacer algunas modificaciones en el código de la pagina para que el código que acabamos de poner en la plantilla funcione.

Vamos a modificar login.ts de la siguiente manera:


import { Component } from '@angular/core';
import { NavController, AlertController } from 'ionic-angular';
import { TabsPage } from '../tabs/tabs';
@Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class LoginPage {
credenciales = { usuario: '', contrasena: '' };
constructor(public navCtrl: NavController, public alertCtrl: AlertController) { }
iniciarSesion() {
if (this.credenciales.usuario === 'user' && this.credenciales.contrasena === '123') {
this.navCtrl.setRoot(TabsPage);
} else {
let alert = this.alertCtrl.create({
title: 'Error',
subTitle: 'Usuario y/o contraseña incorrecta.',
buttons: ['Cerrar']
});
alert.present(prompt);
}
}
}

view raw

login1.ts

hosted with ❤ by GitHub

En la línea 2 importamos el controlador AlertController, el cual vamos a utilizar para mostrar alertas, en la línea 3 importamos la página TabsPage, en la línea 10 creamos e inicializamos el objeto credenciales, el cual vamos a utilizar como modelo de la vista para guardar el usuario y la contraseña, en la 12, como parte del constructor adicionamos la inyección del controlador AlertController y en la línea 14 comenzamos a implementar el método “iniciarSesion()”; este método va a validar que el usuario sea “user” y la contraseña sea “123”, de ser así nos envía a la página TabsPage, la cual es la que define los tabs, siempre que vayamos a esta página se van a mostrar los tabs y el primer tab estará activo, de los contrario mostraremos una alerta diciendo “Usuario y/o contraseña incorrecta.”.

En este momento si ejecutamos ionic serve podremos probar todo lo que hemos implementado hasta ahora:

login-page
Inicio de sesión

Colocar la lógica de inicio de sesión en el código de la página no es una muy buena decisión de diseño ya que rompe con el principio “Open/Closed” de SOLID, hace un tiempo escribí sobre este principio en Swift pero la idea es la misma de forma general. Entonces vamos a extraer esto hacia un proveedor y para generar este nuevo proveedor vamos a utilizar otro generador de Ionic, en la consola, ejecutamos:

ionic g provider auth

Es muy parecido a como generamos la página, sólo cambiamos page por provider, y nos genera este código en el archivo “src/providers/auth.ts“:


import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class Auth {
constructor(public http: Http) {
console.log('Hello Auth Provider');
}
}

view raw

auth1.ts

hosted with ❤ by GitHub

Ahora toca mover el código que valida el inicio de sesión hacia este proveedor, para este ejemplo, este código es muy sencillo, en una aplicación real lo más seguro es que tengamos que conectarnos a algún servicio web para realizar esta validación, utilizar observables y/o promesas.

Luego de la refactorización, el proveedor quedaría de la siguiente manera:


import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
@Injectable()
export class Auth {
constructor() { }
iniciarSesion(credenciales): boolean {
if (credenciales.usuario === 'user' && credenciales.contrasena === '123') {
return true;
} else {
return false;
}
}
}

view raw

auth2.ts

hosted with ❤ by GitHub

Necesitamos ajustar la página LoginPage para que ahora utilice este proveedor:


import { Component } from '@angular/core';
import { NavController, AlertController } from 'ionic-angular';
import { TabsPage } from '../tabs/tabs';
import { Auth } from '../../providers/auth';
@Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class LoginPage {
credenciales = { usuario: '', contrasena: '' };
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public auth: Auth) { }
iniciarSesion() {
if (this.auth.iniciarSesion(this.credenciales)) {
this.navCtrl.setRoot(TabsPage);
} else {
let alert = this.alertCtrl.create({
title: 'Error',
subTitle: 'Usuario y/o contraseña incorrecta.',
buttons: ['Cerrar']
});
alert.present(prompt);
}
}
}

view raw

login2.ts

hosted with ❤ by GitHub

Noten que ahora en la línea 5 importamos el proveedor, luego lo inyectamos en el constructor en la línea 14 y lo utilizamos en la línea 17 para validar las credenciales.

Un último paso que necesitamos realizar es modifica la definición del módulo de nuestra aplicación para registrar el proveedor en la lista de proveedores:


import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { LoginPage } from '../pages/login/login';
import { Auth } from '../providers/auth';
@NgModule({
declarations: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage,
LoginPage
],
providers: [{ provide: ErrorHandler, useClass: IonicErrorHandler }, Auth]
})
export class AppModule { }

view raw

app.module2.ts

hosted with ❤ by GitHub

Veamos cómo en la línea 10 importamos el proveedor Auth y lo registramos en la línea 33 como parte de los proveedores.

Y esto es todo, pudimos ver a través de un ejemplo sencillo cómo utilizar los dos generadores de Ionic 2. Espero les sea útil.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s