Tutorial de IONIC: Componentes personalizados

Hola a todos, en posts anteriores hemos aprendido a crear apps multiplataforma con Ionic.

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

Ionic nos ofrece un montón de componentes ya creados para utilizar en nuestras apps y realmente nos permiten con poco esfuerzo crear una interfaz funcional para nuestras aplicaciones.

Sin embargo hay momentos que puede interesarnos crear nuestros propios componentes personalizados.

Un componente es simplemente algo que podemos mostrar las veces que queramos en la pantalla, como si fuese una etiqueta html, solo que a su vez un componente puede estar formado por varias etiquetas html y otros componentes.

Para ver mejor cómo podemos crear nuestro propios componentes personalizados en Ionic vamos a crear un proyecto de prueba a que vamos a llamar miComponente:

ionic start ejemploTabs tabs

 

Seleccionamos Angular como framework y una vez creado el proyecto si  entramos en home.page.ts veremos esto:

import { Component } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})

export class HomePage {

  constructor() {}

}

En Ionic todo son componentes, de hecho las páginas de nuestra aplicación son componentes, si nos fijamos tiene un decorador @Component por lo que podemos ver que la propia página es un componente  que tiene el selector ‘app-home’ y como plantilla utiliza el archivo home.page.html.

Si inspeccionamos el código que genera ionic en el navegador veremos que tenemos un elemento llamado ion-router-outlet que es la etiqueta principal donde se renderizan las páginas, y dentro de esta tenemos una etiqueta app-home.

Tal y como hemos comentado las páginas también son componentes y para mostrar componentes en la plantilla se utiliza la etiqueta con el nombre del selector del componente que en este caso es app-home, por defecto los componentes llevan el prefijo app- por delante del nombre del componente.

Vamos a crear un sencillo componente al que vamos a llamar saluda, para ello vamos a echar mano de ionic generator, lo primero que vamos a crear es un módulo para declarar nuestros componentes y poder luego invocarlos desde cualquier página donde los necesitemos.

Nos situamos dentro la carpeta de  nuestro proyecto en la consola de comandos y tecleamos lo siguiente:

ionic g module components

Esto nos habrá creado una carpeta llamada components y dentro un archivo llamado components.module.ts con el siguiente contenido:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';



@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ]
})
export class ComponentsModule { }

Ahora vamos a crear nuestro nuevo componente saluda:

 ionic g component components/saluda

 

Esto nos creará una carpeta llamada saluda dentro de components con nuestro componente.

En la carpeta de nuestro componente tendremos un archivo .html para la plantilla, un archivo .scss para los estilos y un archivo .ts con el controlador.

Si observamos lo que contiene el archivo saluda.component.html vemos que simplemente muestra un párrafo con el texto “saluda works!”:

<p>
 saluda works!
</p>

Veamos ahora que tenemos en el archivo  saluda.component.ts:

import { Component, OnInit } from '@angular/core';
 
@Component({
 selector: 'app-saluda',
 templateUrl: './saluda.component.html',
 styleUrls: ['./saluda.component.scss'],
})
export class SaludaComponent implements OnInit {
 
 constructor() { }
 
 ngOnInit() {}
 
}

Como vemos el controlador de un componente es prácticamente igual que el de una página.

Tenemos el decorador @Component donde se indica que su selector es ‘app-saluda‘, que la ruta de la plantilla que utiliza es ./saluda.component.html  y la ruta de los estilos que utilizará es ./saluda.component.scss.

Ahora vamos a importar SaludaComponent en el módulo components.module.ts y lo vamos a declarar en la sección declarations y en la sección exports:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SaludaComponent } from './saluda/saluda.component';
 
@NgModule({
 declarations: [SaludaComponent],
 imports: [
   CommonModule
 ],
 exports: [SaludaComponent]
})
export class ComponentsModule { }

Ahora para poder utilizar nuestro componente en cualquier página solo tenemos que importar ComponentModule en el módulo de nuestra página y declararlo en los imports, por lo tanto vamos a editar home.module.ts e importar el módulo ComponentsModule:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { ComponentsModule } from '../components/components.module';

import { HomePage } from './home.page';

@NgModule({
 imports: [
   CommonModule,
   FormsModule,
   IonicModule,
   ComponentsModule,
   RouterModule.forChild([
     {
       path: '',
       component: HomePage
     }
   ])
 ],
 declarations: [HomePage]
})
export class HomePageModule {}


Para mostrar nuestro componente en la página home editamos el archivo home.page.html, eliminamos todo lo que hay dentro de ion-content y añadimos la etiqueta con el componente que acabamos de crear:

<ion-header>
 <ion-toolbar>
   <ion-title>
     Ionic Blank
   </ion-title>
 </ion-toolbar>
</ion-header>
 
<ion-content>
 <div class="ion-padding">
   <app-saluda></app-saluda>
 </div>
</ion-content>

Así de fácil. Si ejecutamos nuestra app de ejemplo veremos algo similar a esto:

A nuestro componente le podemos añadir también atributos personalizados.
Por ejemplo podemos pasarle un atributo nombre de esta manera:

<ion-header>
 <ion-toolbar>
   <ion-title>
     Ionic Blank
   </ion-title>
 </ion-toolbar>
</ion-header>
 
<ion-content>
 <div class="ion-padding">
   <app-saluda nombre="Eduardo"></app-saluda>
 </div>
</ion-content>

Luego en el controlador de nuestro componente (saluda.component.ts) definimos el parámetro de entrada con el decorador Input de la siguiente manera:

import { Component, OnInit, Input } from '@angular/core';
 
@Component({
 selector: 'app-saluda',
 templateUrl: './saluda.component.html',
 styleUrls: ['./saluda.component.scss'],
})
export class SaludaComponent implements OnInit {
 
 @Input() nombre: string;
 constructor() { }
 
 ngOnInit() {}
 
}

Para poder utilizar el decorador Input debemos importarlo primero.

Ahora podemos hacer que en lugar de mostrar en pantalla “saluda works!” salude a la persona que recibamos en el parámetro nombre, para ello vamos a crear una variable que llamaremos text y a la que en el constructor le daremos el valor ‘¡Hola’ concatenando el nombre que recibe como input:

import { Component, OnInit, Input } from '@angular/core';
 
@Component({
 selector: 'app-saluda',
 templateUrl: './saluda.component.html',
 styleUrls: ['./saluda.component.scss'],
})
export class SaludaComponent implements OnInit {
 
 @Input() nombre: string;
 text: string;
 
 constructor() {
   this.text = '¡Hola '+this.nombre+'!';
 }
 
 ngOnInit() {}
 
}

Ahora en la plantilla saluda.component.html vamos a hacer que se muestre el contenido de la variable text:

<p>
{{ text }}
</p>

Bien, si como en el ejemplo hemos pasado “Eduardo” al parámetro nombre cabría esperar ver en pantalla “¡Hola Eduardo!”, sin embargo comprobamos que muestra “¡Hola undefined!”, es evidente que hay algo que no está funcionando.

Esto ocurre porque estamos accediendo a la variable this.nombre desde el constructor, y en el momento que se ejecuta el constructor aún no están accesibles los parámetros que recibimos en nuestro componente, para ello utilizamos ngOnInit que se ejecuta cuando nuestro componente se ha inicializado y tenemos acceso a los parámetros:

import { Component, OnInit,  Input  } from '@angular/core';

@Component({
  selector: 'app-saluda',
  templateUrl: './saluda.component.html',
  styleUrls: ['./saluda.component.scss'],
})
export class SaludaComponent implements OnInit {

  @Input() nombre: string;
  text: string;

  constructor() {
  }

  ngOnInit() {
    this.text = '¡Hola ' + this.nombre + '!';
  }

}

Ahora podemos comprobar que muestra el nombre que le hayamos pasado.

También podemos utilizar la la variable nombre directamente en la plantilla de nuestro componente de esta manera:

<p>
¡Hola {{ nombre }}!
</p>

Por último si en lugar de pasarle directamente el nombre al componente queremos utilizar una variable debemos poner el parámetro entre corchetes, por ejemplo imaginemos que tenemos un array de usuarios  y queremos saludarles a todos, en home.page.ts definimos un array de usuarios:

import { Component } from '@angular/core';
 
@Component({
 selector: 'app-home',
 templateUrl: 'home.page.html',
 styleUrls: ['home.page.scss'],
})
export class HomePage {
 
 usuarios: any = [
   {
     nombre: 'Eduardo',
     edad: 41
   },
   {
     nombre: 'Pedro',
     edad: 28
   },
   {
     nombre: 'Francisco',
     edad: 34
   },
   {
     nombre: 'Maria',
     edad: 43
   }
 ];
 
 constructor() {}
 
}

Ahora en home.page.html podemos recorrer el array con *ngFor y mostrar nuestro componente saludo pasándole la variable usuario.nombre:

<ion-header>
 <ion-toolbar>
   <ion-title>
     Ionic Blank
   </ion-title>
 </ion-toolbar>
</ion-header>
 
<ion-content>
 <div class="ion-padding">
   <app-saluda  *ngFor="let usuario of usuarios" [nombre]="usuario.nombre"></app-saluda>
 </div>
</ion-content>

Como podemos ver en este caso el parámetro nombre va entre corchetes []  ya que lo que le pasamos no es un texto literal sino una variable.

Si probamos este ejemplo veremos algo como esto:

Este ejemplo es muy sencillo y es solo para explicar cómo funcionan los componentes en Ionic, evidentemente no merece la pena crear un componente que solo contenga un div y un texto, pero podemos ampliar nuestro componente añadiendo una imagen o una ficha completa con los datos del usuario, o cualquier otro elemento que se nos ocurra.

Puedes descargar o clonar este proyecto desde GitHub en el siguiente link: 

Este ejemplo es muy sencillo y es solo para explicar cómo funcionan los componentes en Ionic, evidentemente no merece la pena crear un componente que solo contenga un div y un texto, pero podemos ampliar nuestro componente añadiendo una imagen o una ficha completa con los datos del usuario, o cualquier otro elemento que se nos ocurra.

Puedes descargar o clonar este proyecto desde GitHub en el siguiente link: 

https://github.com/edurevilla/libro-ionic-5-componentes-personalizados

 

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.

 

Deja un comentario

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.