Directiva ngClass en Angular 2

  • Por
Estudio de la directiva ngClass de Angular 2, ejemplo práctico de un componente que usa esa directiva.

Después de varios artículos un tanto densos de en el Manual de Angular 2 vamos a estudiar algunas cosas un poco más ligeras, que nos permitirán practicar con el framework sin añadir mucha complejidad a lo que ya conocemos. Para ello vamos a hacer una serie de pequeños artículos acerca de las directivas de Angular 2 más útiles en el día a día del desarrollo de aplicaciones.

Comenzamos con la directiva ngClass, que nos permite alterar las clases CSS que tienen los elementos de la página. Lo veremos en el marco del desarrollo de aplicaciones Angular con un ejemplo básico.

Si vienes de Angular 1.x verás que las directivas han perdido un poco de protagonismo en el desarrollo en Angular 2. Muchas de las antiguas directivas han desaparecido y su uso ha sido sustituido por otras herramientas diversas. Como norma ahora en Angular 2 las directivas se usarán para solucionar necesidades específicas de manipulación del DOM y otros temas estructurales.

Nota: Los componentes también pueden ser considerados como un tipo de directiva, aunque en este caso se usan para resolver problemas de negocio, como ya se introdujo en el artículo sobre las características básicas de los componentes.

No todos los problemas de clases se necesitan resolver con ngClass

Lo primero es decir que la directiva ngClass no es necesaria en todos los casos. Las cosas más simples ni siquiera la necesitan. El atributo "class" de las etiquetas si lo pones entre corchetes funciona como propiedad a la que le puedes asignar algo que tengas en tu modelo. Esto lo vimos en el artículo sobre la sintaxis de las vistas.

<h1 [class]="claseTitular">Titular</h1>

En este caso, "claseTitular" es una variable del modelo, algo que me pasa el controlador que tendrás asociado a un componente.

export class PruebaComponent implements OnInit {
  claseTitular: string = "class1";
  
  cambiaEstado() { 
    this.claseTitular = "class2"
  }

  ngOnInit() {
  }

}

La class del H1 valdrá lo que haya en la variable claseTitular. Cuando alguien llame al método cambiaEstado() se modificaría el valor de esa variable y por tanto cambiaría la clase en el encabezamiento.

Si esto ya resuelve la mayoría de las necesidades que se nos ocurren ¿para qué sirve entonces ngClass?

Asignar clases CSS con ngClass

La directiva ngClass es necesaria para, de una manera cómoda asignar cualquier clase CSS entre un grupo de posibilidades. Puedes usar varios valores para expresar los grupos de clases aplicables. Es parecido a como funcionaba en Angular 1.x.

A esta directiva le indicamos como valor:

1. Un array con la lista de clases a aplicar. Ese array lo podemos especificar de manera literal en el HTML.

<p [ngClass]="['negativo', 'off']">Pueden aplicarse varias clases</p>

O por su puesto podría ser el nombre de una variable que tenemos en el modelo con el array de clases creado mediante Javascript.

<p [ngClass]="arrayClases">Pueden aplicarse varias clases</p>

Ese array lo podrías haber definido del lado de Javascript.

clases = ['positivo', 'si'];

2. Un objeto con propiedades y valores (lo que sería un literal de objeto Javascript). Cada nombre de propiedad es una posible clase CSS que se podría asignar al elemento y cada valor es una expresión que se evaluará condicionalmente para aplicar o no esa clase.

<li [ngClass]="{positivo: cantidad > 0, negativo: cantidad < 0, off: desactivado, on: !desactivado }">Línea</li>

Ejemplo de aplicación de ngClass

Vamos a hacer un sencillo ejemplo de un componente llamado "BotonSino" que simplemente muestra un mensaje "SI" o "NO". Al pulsar el botón cambia el estado. Cada estado se representa además con una clase que aplica un aspecto.

Nota: No vamos a explicar las partes del componente porque se vieron con detalle en los artículos anteriores del Manual de Angular 2. Consultar toda la parte de desarrollo de componentes para más información.

Nuestro HTML es el siguiente:

<p>
  <button 
    [ngClass]="{si: estadoPositivo, no: !estadoPositivo}"
    (click)="cambiaEstado()"
  >{{texto}}</button>
</p>

La etiqueta button tiene un par de atributos que son los que hacen la magia. Entre corchetes se aplica la directiva "ngClass", con un valor de objeto. Entre paréntesis se aplica el evento "click", con la invocación de la función encargada de procesar la acción. Además, el texto del botón es algo que nos vendrá de la variable "texto".

Nuestro Javascript será el siguiente:

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

@Component({
  moduleId: module.id,
  selector: 'app-boton-sino',
  templateUrl: 'boton-sino.component.html',
  styleUrls: ['boton-sino.component.css']
})
export class BotonSinoComponent implements OnInit {

  texto: string =  "SI";
  estadoPositivo: boolean = true;

  cambiaEstado() {
    this.texto = (this.estadoPositivo) ?  "NO" : "SI";
    this.estadoPositivo = !this.estadoPositivo; 
  }

  ngOnInit() {
  }

}

Como sabes, este código TypeScript es la mayoría generado por Angular CLI. Lo que hemos hecho nosotros es lo que está dnetro de la clase BotonSinoComponent.

En ella creamos las propiedades necesarias en la vista y el método que se encarga de procesar el cambio de estado.

Nuestro CSS:

Lógicamente, para que esto funcione necesitaremos declarar algunos estilos sencillos, al menos los de las clases que se usan en el HTML.

button {
    padding: 15px;
    font-size: 1.2em;
    border-radius: 5px;
    color: white;
    font-weight: bold;
    width: 70px;
    height: 60px;
}
.si{
    background-color: #6c5;
}
.no{
    background-color: #933;
}

Con esto es todo! Es un ejemplo muy sencillo que quizás para los que vienen de Angular 1.x resulte demasiado básico, pero seguro que lo agradecerán quienes estén comenzando con Angular en estos momentos. Más adelante lo complicaremos algo. Realmente la dificultad mayor puede ser seguir los pasos para la creación del componente y luego los pasos para su utilización, pero eso ya lo hemos explicado anteriormente.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Brais

02/10/2016
error al ejecutar
Hola, estoy siguiendo el manual, pero al ejecutar el código aquí expuesto me da el siguiente error:

Error: @http://localhost:4200/system-config.js:35:5
Call@http://localhost:4200/vendor/es6-shim/es6-shim.js:289:14
forEach@http://localhost:4200/vendor/es6-shim/es6-shim.js:1295:14
@http://localhost:4200/system-config.js:34:1
Zone</ZoneDelegate</ZoneDelegate.prototype.invoke@http://localhost:4200/vendor/zone.js/dist/zone.js:323:20
Zone</Zone</Zone.prototype.run@http://localhost:4200/vendor/zone.js/dist/zone.js:216:25
scheduleResolveOrReject/<@http://localhost:4200/vendor/zone.js/dist/zone.js:571:53
Zone</ZoneDelegate</ZoneDelegate.prototype.invokeTask@http://localhost:4200/vendor/zone.js/dist/zone.js:356:24
Zone</Zone</Zone.prototype.runTask@http://localhost:4200/vendor/zone.js/dist/zone.js:256:29
drainMicroTaskQueue@http://localhost:4200/vendor/zone.js/dist/zone.js:474:26
ZoneTask/this.invoke@http://localhost:4200/vendor/zone.js/dist/zone.js:426:22

Evaluating http://localhost:4200/system-config.js
Error loading http://localhost:4200/system-config.js

no tengo ningún error ts. Se que algo estoy haciendo mal pero no entiendo el que.

alguna sugerencia?

Gesplanet

07/2/2017
Componentes propios
El problema igual es que en esta versión no hay que declarar nada, yo creo el componente, lo inserto con:
<app-mi-componente></app-mi-componente>

y no necesito ponerlo ni declararlo en ningún sitio, debe ser cosa de las versiones, que en la que acabo de instalar no hace falta ya.

Enhora buena por por el tutorial, me está siendo de gran ayuda para empezar.

Cristianf

30/12/2017
excelente
me fue de mucha ayuda !, sigue asi, saludos!