Quantcast

Modals Ionic | Todo lo que tienes que saber y más

Aitor Sánchez - Blog - Oct. 26, 2023, 12:13 p.m.

¿Necesitas mostrar algo a un usuario de tu app a través ventanas modales, o modals, en Ionic? O, tal vez, ya sabes cómo se hace esto y estás buscando cómo funciona algún campo o lo alguna de sus funciones ¿verdad?

Mi nombre es Aitor Sánchez, soy desarrollador de apps desde 2014, y en este artículo te enseñaré a mostrar modales en Ionic, de una manera práctica, sencilla e intuitiva así que no te lo puedes perder ¡vamos al lío!

Pero antes de continuar, esta es la Flutter Mafia. Es mi newsletter donde aprenderás desarrollo de apps móviles, aso y monetización junto con otros genietes que ya están dentro. Y si te suscribes te regalo mi ebook "Duplica los ingreso de tus apps en 5 minutos" No es broma, quizás te interese.

 

Instalación de Modals en Ionic

Al tratarse de un componente de sistema, y al no acceder a funciones nativas, ion-modal ya viene instalado por defecto.

Ionic da por hecho que lo vas a usar en tus aplicaciones.

 

Configurando el componente

Sucede lo mismo que en punto anterior. No necesita configuración previa porque ya viene instalado.

Así que continuemos con lo que nos atañe ;P

 

Modales en Ionic, qué son y cómo se utilizan

Comenzamos hablando de que son los modals.

 

Nota: No son modales cómo los que tenemos en la web. En este caso, el modal se superpondrá al contenido que estemos viendo en pantalla usando toda esta.

Podríamos decir, que es cómo una vista a pantalla completa o cómo si se tratara de una página normal y corriente.

 

Se usará un componente para la vista que contiene, y le puedes pasar parámetros de una manera muy sencilla. Pero veamos sobre código que todo se ve mejor.

 

Ejemplo de cómo se crea el modal

En primer lugar, y por si tienes un poco  de prisa, un ejemplo práctico vale más que mil palabras:

import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { ModalPage } from '../modal/modal.page';

@Component({
  selector: 'modal-example',
  templateUrl: 'modal-example.html',
  styleUrls: ['./modal-example.css']
})

export class ModalExample {

  constructor(public modalController: ModalController) {
  }

  async presentModal() {
    const modal = await this.modalController.create({
      component: ModalPage
    });
    return await modal.present();
  }
}

 

Y ahora el “ModalPage” antes de continuar.

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

@Component({
  selector: 'modal-page',
})
export class ModalPage {

  constructor() {

  }

}

 

Vale, hasta aquí sencillote. En primer lugar, inyectas en el constructor una instancia de ModalController. Dicha instancia te permite controlar cómo, y de que manera, vas a mostrar dichas ventanas emergentes.

 

Nota: Para hacer esto, es necesario realizar un import antes, que no se nos olvide.

 

Y posteriormente, con el método “create”, construyes el modal que será mostrado en el ejemplo.

Cómo componente llamaremos a un puntero de la clase ModalPage. Esta clase "ModalPage" será un componente propio, como se ve en el ejemplo.

 

Si no sabes lo que es, pásate por aquí: https://ionicframework.com/docs/components

 

Y una vez finalizados estos pasos, llamas a la función “present” y ya tendrías tu flamante modal en pantalla.

 

Cómo destruir un Modal con el método dismiss

Ya has aprendido a crear y a mostrar Modales en nuestra app. Ahora le toca el turno a un paso igual de importante que es destruirlos.

En este caso, vas a llamarlo dismisear y lo único que hará es eliminar de la pantalla el modal.

Para tal fin, vas a usar la función “dismiss()” sobre la instancia de tu modal. Y si, el modal se destruiría. Lo puedes usar tanto dentro de la promesa, cómo fuera, así que las posibilidades son ilimitadas.

 

export class ModalPage {

  ...

  dismiss() {
    // using the injected ModalController this page
    // can "dismiss" itself and optionally pass back data
    this.modalCtrl.dismiss({
      'dismissed': true
    });
  }
}

 

Déjame que te aclare que podemos recuperar datos que queramos enviar desde el modal cuando lo cerramos hacia la instancia que lo ha abierto de la siguiente manera:

 

const { data } = await modal.onWillDismiss();
console.log(data);

 

Y funciona tanto con “onWillDismiss” que con “onDidDismiss”.

 

Cómo pasar variables a mis modals en Ionic

Otra idéa común es pasar datos mi modal a otro. Y esto es lo que vamos a ver ahora, algo sencillo, práctico y muy intuitivo.

Veamos un ejemplo primero:

 

async presentModal() {
  const modal = await this.modalController.create({
    component: ModalPage,
    componentProps: {
      'nombre': 'Aitor',
      'apellidos': 'Sánchez',
      'locale': 'es_ES'
    }
  });
  return await modal.present();
}

 

En el caso en cuestión, usaremos “componentProps”. Que es, ni más ni menos, que un objeto para pasarle datos, en esta caso de una persona, a nuestros modals page.

 

Más info sobre los "componentProps" aquí

 

Estás utilizando también el “ModalPage” que has usado en el ejemplo anterior.

Y así quedaría listo el ejemplo. Si quieres enviar más, pues metes más parámetros. Y listo :)

 

Cómo recuperar datos desde un Ionic modal

Para recuperar los datos desde un modal que hemos lanzado previamente, cómo hemos visto en el ejemplo anterior, tienes dos opciones.

La primera, y más sencilla, es utilizar la clase “NavParams”. Los datos los puedes recuperar de la siguiente manera:

 

export class ModalPage {

  constructor(navParams: NavParams) {
    console.log(navParams.get('nombre'));
    console.log(navParams.get('apellidos'));
    console.log(navParams.get('locale'));
  }

}

 

O bien usar el decorador “@input” que nos dará acceso a lo que lleva el dispositivo en memoria con el nombre de la variable. Ejemplo:

 

export class ModalPage {

  // Data passed in by componentProps

  @Input() firstName: string;
  @Input() lastName: string;
  @Input() middleInitial: string;

  constructor() {

  }

}

 

Perfecto, ahora vas a pasar a ver un poco más de chicha. Por chicha me refiero a las propiedades, los eventos, los métodos y las propiedades CSS. Adelante…

 

Propiedades de las ventanas modales

  • Animated
    • Si es verdadero, el modal se animará al aparecer y al eliminarse.
    • Atributo -> animated.
    • Tipo -> booleano.
    • Por defecto -> true
  • backdropDismiss
    • Si es verdadero, el modal podrá cerrarse pulsando fuera de él.
    • Atributo -> backdrop-dismiss
    • Tipo -> Booleano
    • Default -> true
  • Component
    • El componente que será mostrado dentro del modal.
    • Atributo -> component
    • Tipo -> Function | HTMLElement | null | string
  • componentProps
    • Los datos que vas a pasar al modal en un objeto de pares “ key = >val ”.
    • Atributo -> Se asignará desde el código TS en la construcción.
    • Tipo -> undefined | { [key: string]: any; }
  • cssClass
    • Clases adicionales para aplicarle al componente. Si quieres poner más de una clase hay que separarlas por espacios o enviar un array de Strings.
    • Atributo -> css-class.
    • Tipo -> string | string[] | undefined
  • enterAnimation
    • La animación que vamos a usar cuando se presente el modal.
    • Tipo -> Será una promesa con la siguiente nomenclatura:
      • ((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) | undefined
      • Nos llegará la animación terminada para que podamos continuar.
  • keyboardClose
    • Si es verdadero, el teclado se esconderá cuando el modal sea mostrado.
    • Atributo -> keyboard-close
    • Tipo -> Booleano
    • Por defecto -> true
  • leaveAnimation
    • La animación que se va a utilizar cuando el modal se elimina.
    • Tipo -> Será una promesa que tendrá la siguiente nomenclatura:
      • ((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) | undefined
      • Nos llegará la animación con el resultado.
    • mode
      • El mode determina qué estilos de plataforma usar.
      • Atributo -> mode.
      • Tipo -> “ios” | “md”.
  • showBackdrop
    • SI es verdadero, muestra un fondo detrás del modal.
    • Atributo -> show-backdrop
    • Tipo -> Booleano
    • Por defecto -> true

 

Eventos de los modals

Lleegados a este punto, quizás se está haciendo un poco pesado el tutorial. Pero bueno, ya queda menos. Solo te pido un poco más de tu tiempo, no te arrepentirás.

Ahora vas a ver los disparadores, o listeners, cómo quieras llamarlos.

Que, al fin y al cabo, son los eventos que disparan los usuarios al interactuar con el modal.

Son los siguientes:

  • ionModalDidDismiss -> Se emite después de que el modal se haya destruido.
  • ionModalDidPresent -> Emitido después de que el modal se haya mostrado.
  • ionModalWillDismiss -> Se emite antes de que el modal vaya a ser destruido.
  • ionModalWillPresent -> Emitido antes de que el modal vaya a ser mostrado.

 

Y ahora vas a ver un ejemplo de código completo donde utilizo los 3 callbacks en un caso real para mostrar información sobre un libro.

 

"book-info-modal.component.html"

 

<ion-header>
  <ion-toolbar>
    <ion-title>Información del Libro</ion-title>
    <ion-buttons slot="end">
      <ion-button (click)="dismissModal()">Cerrar</ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <h2>{{ book.title }}</h2>
  <p>{{ book.author }}</p>
  <p>{{ book.description }}</p>
</ion-content>

 

"book-info-modal.component.ts"

 


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

@Component({
  selector: 'app-book-info-modal',
  templateUrl: 'book-info-modal.component.html',
})
export class BookInfoModalComponent {
  @Input() book: any; // Asumiendo que book es un objeto con title, author, description, etc.

  constructor(private modalController: ModalController) {}

  dismissModal() {
    this.modalController.dismiss();
  }
}

 

"mi-component.ts"

 


import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { BookInfoModalComponent } from './book-info-modal.component'; // Asegúrate de tener la ruta correcta

@Component({
  selector: 'mi-componente',
  templateUrl: 'mi-componente.html',
})
export class MiComponente {
  book = { title: 'Ejemplo de Libro', author: 'Autor Ejemplo', description: 'Descripción del libro...' };

  constructor(public modalController: ModalController) {}

  async presentModal() {
    const modal = await this.modalController.create({
      component: BookInfoModalComponent,
      componentProps: { book: this.book },
      // Captura de eventos
      willPresent: () => console.log('Modal will present'),
      didPresent: () => console.log('Modal did present'),
      willDismiss: () => console.log('Modal will dismiss'),
      didDismiss: () => console.log('Modal did dismiss')
    });

    modal.present();
  }
}

 

"mi-component.html"

 

<ion-button (click)="presentModal()">Mostrar Información del Libro</ion-button>

 

En el código del ejemplo:

  • En mi-componente.ts, se crea un modal usando ModalController y se configuran los eventos willPresent, didPresent, willDismiss y didDismiss.
  • El componente modal BookInfoModalComponent recibe los datos del libro a través de componentProps.
  • En el archivo HTML del modal, se muestra la información del libro y se proporciona un botón para cerrar el modal.

 

 

Recuerda: En los tutoriales no voy a meter los eventos de los padres de la clase. No tendría sentido.

 

La verdad que no son muchos, es lógico. Si lo piensas, dime ¿qué más opciones de eventos puede tener qué sean propias? No me vengan con el Swipe, que ya lo tiene el padre.

Y con esto pasas a la última sección. Los métodos de clase, comenzamos…

 

Métodos de Ion-modal

  • Dismiss
    • Destruye el modal que tenemos en pantalla. Si no está no hace nada.
    • dismiss(data?: any, role?: string | undefined)
    • Devuelve una promesa que tenemos que controlar. En ella llega un booleano que nos permite definir si se ha realizado correctamente.
  • onDidDismiss
    • Nos permite suscribirnos al evento desde código.
    • onDidDismiss()
    • Devuelve una promesa que contiene una instancia de “OverlayEventDetail” Que se resolverá cuando el modal haya sido destruido.
  • onWillDismiss
    • Similar al anterior, pero se dispara antes de que el modal se muestre.
  • Present
    • Presenta un modal que se ha creado previamente a través de modalController.
    • “present()”
    • Devuelve una promesa que tendremos que controlar. Aunque llega vacía, nos avisa de cuando ha terminado de mostrarse el modal.

 

Y estas son todas las funciones, o métodos, que nos vamos a encontrar de esta clase. Y para terminar, y acabar ya con esta pesadilla :P Vamos a ver las propiedades CSS. Terminemos de una vez…

 

Ahora, las propiedades CSS

Pues cómo en todos los componentes HTML, tienes una variedad de opciones por las que puedes optar a la hora de darle diseño a tus módulos. Vamos a verlas:

  • --background -> EL fondo del modal quedando por detrás del contenido componente que hemos asignado.
  • --boder-color -> El color del borde.
  • --border-radius -> En caso de que queramos, el redondeo del borde del modal.
  • --border-style -> El estilo del borde del modal.
  • --border-width -> El ancho del borde.
  • --height -> El alto del modal.
  • --max-height -> El alto máximo del modal.
  • --max-width -> El ancho máximo del modal.
  • --min-height -> El alto mínimo.
  • --min-width -> El ancho mínimo.
  • --width -> El ancho fijo del modal.

Cómo podrás apreciar, y cómo digo siempre, estas son las propiedades de esta clase. Luego hereda todas las del padre, cómo es lógico. Así que, si falta alguna, no lo tengas en cuenta. Seguramente esté en alguno de los padres. Revísalo, y si de verdad falta, y me lo quieres comunicar, estaré encantado de revisarlo :P

 

Estilos personalizados

En caso de que estes buscando mostrar una ventana emergente personalizada, cómo pasa  en buena parte de las aplicaciones, puedes darle al método "create" del modalController una clase CSS que hayas creado explícitamente para este fin:

 

constructor (private modalController: ModalController) {
}

async openMyModal() {
  const myModal = await this.modalController.create({
    component: MyModalPage,
    cssClass: 'my-custom-modal-css'
  });
  return await myModal.present();
}

 

Y la clase CSS podría ser la siguiente:

.my-custom-modal-css .modal-wrapper {
   height: 20%;
   top: 80%;
   position: absolute; 
   display: block;  
}

 

Así, de esta manera, cambiarás todos los atributos que veas oportunos. El size, el width, el color, etc... Así suplirás las posibles carencias que pudiese tener el punto anterior para adaptarse a tus necesidades.

 

Y para terminar, el tutorial en vídeo

 

 

Algo más que quizás te interese

Mira, en el momento que tu mejoras el logo de una app que tengas publicada en Google Play, las descargas y los ingresos que esta aplicación genera aumentan. Esto es así. Mejor logo es igual a más dinero.

Basándonos en esto, hemos creado esta herramienta que te permite evaluar, optimizar y mejorar los logos de tus apps para que reciban más descargas. No te quiero espoilear, dentro hay un video explicativo. Entra en el enlace.

 

Y ahora si geniete. Espero haberte ayudado y nos vemos en el siguiente artículo. Hasta ese entonces ¡que te vaya bien!

Otros artículos que te pueden interesar

Intercom Ionic | Qué es y cómo puedes utilizarlo

¿Interesado en implementar la api Intercom Ionic en tu aplicación? O, quizás...

Auto Start Ionic | Cómo ejecutar mi app cuando ...

¿Necesitas iniciar automáticamente tu aplicación cuando se enciende el dispo...

Google Analytics Ionic | Aprende a usarlo cómo ...

¿Pensando en realizar un seguimiento de los usuarios en tu app? O quizás ya sabes l...