Archivo de la etiqueta: componentes personalizados ionic

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

 

Como crear componentes personalizados con Ionic

 

¡¡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 posts anteriores hemos aprendido a crear nuestras apps multiplataforma con Ionic.
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.

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

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 etiquetas html y otros componentes.

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

ionic start miComponente blank

Una vez creado el proyecto si  entramos en home.ts veremos esto:

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

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

  constructor(public navCtrl: NavController) {

  }

}

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 pagina es un componente  que tiene el selector ‘page-home’ y como plantilla utiliza el archivo home.html.

Vamos a crear un sencillo componente al que vamos a llamar saludar, para ello vamos a echar mano de ionic generator, nos situamos dentro la carpeta de  nuestro proyecto en la consola de comandos y tecleamos lo siguiente:

ionic g component saluda

Con esto se habrá creado una nueva carpeta llamada components y dentro una carpeta llamada saluda que al igual que las páginas contiene un archivo .ts como controlador, un archivo .scss para los estilos y su plantilla .html.

Si observamos lo que contiene el archivo saluda.html vemos que simplemente muestra el contenido de la variable text dentro de un div:

<!-- Generated template for the SaludaComponent component -->
<div>
  {{text}}
</div>

Vemos que text está definida en el controlador saluda.ts y contiene la famosa frase “Hello Word”

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

/**
 * Generated class for the SaludaComponent component.
 *
 * See https://angular.io/api/core/Component for more info on Angular
 * Components.
 */
@Component({
  selector: 'saluda',
  templateUrl: 'saluda.html'
})
export class SaludaComponent {

  text: string;

  constructor() {
    console.log('Hello SaludaComponent Component');
    this.text = 'Hello World';
  }

}

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 ‘saluda‘ y la plantilla que utiliza es saluda.html.

Para poderlo utilizar tenemos que importar y declarar el componente en app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { SaludaComponent } from '../components/saluda/saluda';


@NgModule({
  declarations: [
    MyApp,
    HomePage,
    SaludaComponent
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

Para utilizarlo en la página home editamos el archivo home.html y añadimos la etiqueta con el componente que acabamos de crear:

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <saluda></saluda>
</ion-content>

Así de fácil.

Si ejecutamos nuestra app de ejemplo con ionic serve -l veremos algo similar a esto:

 

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

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
 <saluda nombre="Eduardo"></saluda>
</ion-content>

Luego en el controlador definimos el parámetro de entrada con el decorador Input de la siguiente manera:

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

/**
 * Generated class for the SaludaComponent component.
 *
 * See https://angular.io/api/core/Component for more info on Angular
 * Components.
 */
@Component({
  selector: 'saluda',
  templateUrl: 'saluda.html'
})
export class SaludaComponent {

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

  constructor() {
    console.log('Hello SaludaComponent Component');
    this.text = 'Hello World';
  }

}

Para poder utilizar el decorador Input debemos importarlo primero.

Ahora podemos hacer que en lugar de saludar al mundo con “Hello Word” salude a la persona que recibamos en el parámetro nombre:

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

/**
 * Generated class for the SaludaComponent component.
 *
 * See https://angular.io/api/core/Component for more info on Angular
 * Components.
 */
@Component({
  selector: 'saluda',
  templateUrl: 'saluda.html'
})
export class SaludaComponent {

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

  constructor() {
    console.log('Hello SaludaComponent Component');
    this.text = 'Hola '+this.nombre;
  }

}

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”, a no ser que tus padres te hayan puesto de nombre undefined hay algo que no está funcionando.

Eso eso es porque estamos accediendo a la variable this.nombre desde el constructor, y en el momento que se ejecuta el constructor aun no están accesibles los parámetros que recibimos en nuestro componente, para ello utilizamos ngOnInit:

/**
 * Generated class for the SaludaComponent component.
 *
 * See https://angular.io/api/core/Component for more info on Angular
 * Components.
 */
@Component({
  selector: 'saluda',
  templateUrl: 'saluda.html'
})
export class SaludaComponent {

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

  constructor() {
    console.log('Hello SaludaComponent Component');
  }


  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:

<!-- Generated template for the SaludaComponent component -->
<div>
  Hola {{ nombre }}
</div>

Por ultimo 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.ts definiriamos un array de usuarios:

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

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

  usuarios: any = [
    { 
      nombre: 'Eduardo',
      edad: 41
    },
    { 
      nombre: 'Pedro',
      edad: 28
    },
    { 
      nombre: 'Francisco',
      edad: 34
    },
    { 
      nombre: 'Maria',
      edad: 43
    }
  ]

  constructor(public navCtrl: NavController) {

  }

}

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

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
 <saluda  *ngFor="let usuario of usuarios" [nombre]="usuario.nombre"></saluda>
</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 como 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.

Espero que estos sencillos ejemplos sirvan para comprender como crear componentes personalizados en Ionic.

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