¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Angular
  3. Los componentes
Extrait - Angular Desarrolle sus aplicaciones web con el framework JavaScript de Google
Extractos del libro
Angular Desarrolle sus aplicaciones web con el framework JavaScript de Google
2 opiniones
Volver a la página de compra del libro

Los componentes

Introducción

Este capítulo presenta la piedra angular de Angular, los componentes. Inicialmente, el objetivo es saber qué es un componente y cuáles son los partes que lo forman. Posteriormente, es primordial abordar los diferentes tipos de argumentos que puede tener un componente: los inputs y outputs. A continuación, en una aplicación, conviven varios componentes y deben interactuar entre ellos, lo que conduce a interacciones entre componentes, concepto que se puede representar en forma de varios mecanismos. Para terminar, se abordarán las nociones más específicas de Angular, como la View Encapsulation y la detección de cambios.

¿Qué es un componente?

1. Una primera definición

El componente es la estructura fundamental de una aplicación Angular. Como podemos encontrar en otros frameworks, o sencillamente con los Web Components, la aplicación se divide en componentes que pueden contener a su vez otros componentes.

Los objetivos principales, que al mismo tiempo son activos, son la reutilización y una descomposición lógica. Supongamos que una aplicación tiene que gestionar una lista de una entidad específica. Tendrá numerosos elementos a visualizar, por medio de una lista, por ejemplo. Por lo tanto, vamos a crear un componente que muestra un único elemento, y va a iterar por él para visualizar todos los elementos.

Por ejemplo, en una página que contiene un encabezado y lista de artículos, se pueden identificar dos componentes: el artículo y el encabezado.

Por lo tanto, la idea es crear estos dos componentes una única vez, y reutilizarlos cuando sea necesario integrarlos.

images/EI06_1.png

La estructura de un componente se descompone en varias partes. En primer lugar, está la declaración del mismo. Posteriormente, en esta declaración, el template del componente y su estilo.

A continuación vienen las herramientas proporcionadas por Angular, como los eventos del DOM, la gestión de las animaciones o las nociones específicas de Angular.

Un componente va a pertenecer a un módulo. Por lo tanto, el componente se declarará en el módulo apropiado.

En lo que respecta a la nomenclatura, los desarrolladores de Angular defienden utilizar component como sufijo del nombre. De esta manera tenemos nombres de componentes del tipo:

  • my-component.ts

  • item.component.ts

  • item-list.component.ts

  • etc.

2. Crear un primer componente

a. Sintaxis inline

Es más fácil aprender el concepto con esta primera sintaxis inline, que se considera rudimentaria, porque la totalidad del código está en un único archivo.

import { Component } from '@angular/core';  
  
@Component({  
    selector: 'app-item',  
    styles:[`div  
    {  
        background:red;  
    }`],  
    template:'<div>Un item </div>'  ...

Los inputs y outputs

1. Los inputs de un componente

a. Declarar una variable como Input

Para que una aplicación basada en componentes pueda funcionar, es esencial poder hacer que los componentes sean configurables. Para esto, Angular proporciona el decorador @Input, que va a permitir identificar una propiedad del componente como input de dicho componente. El input puede ser de cualquier tipo TypeScript, un number, un string, o incluso una clase/interfaz que hayamos creado.

import { Component, Input } from '@angular/core';  
  
@Component({  
    selector: 'app-todo',  
    templateUrl: './todo.component.html',  
    styleUrls: ['./todo.component.css']  
  
})  
export class TodoComponent {  
    @Input()  
    text: string;  
  
    @Input()  
    isChecked: boolean;  
} 

Se importa el decorador @Input desde @angular/core, y lo utilizamos en las propiedades text y isChecked.

Por lo tanto, estas dos propiedades son los inputs del componente Todo y ahora es posible inicializarlos en la etiqueta app-todo.

Propiedades incializadas en duro

  <app-todo text="Hacer los cursos" isChecked="true">  
  </app-todo> 

En el primer ejemplo, se han especificado propiedades "en duro". Es posible pasar propiedades del componente padre. Por ejemplo, con dos propiedades en el componente padre, el componente Todo muestra:

Propiedades del componente padre

  todoChecked: boolean = true;  
  todoName: string = "Hacer los cursos"; 

Es posible dar estas dos propiedades al componente Todo. Para esto, hay que utilizar la sintaxis apropiada, es decir, los corchetes que rodean a las propiedades en el HTML.

  <app-todo [text]="todoName" [isChecked]="todoChecked">  
  </app-todo> 

De esta manera, en cuanto el componente padre modifique las propiedades, el componente Todo se actualizará en consecuencia, porque recibirá los nuevos valores. 

b. Un ejemplo concreto con una lista

Las partes anteriores destacan las sintaxis y los conceptos, pero no explotan totalmente la utilidad de los componentes y de sus inputs. Para entender mejor su interés, vamos...

Interacción entre componentes

Las interacciones entre componentes son un aspecto muy importante, porque los componentes están en el corazón de las aplicaciones Angular. Sin comunicación entre componentes, los desarrollos serían prácticamente imposibles. Afortunadamente, Angular ofrece muchas posibilidades para que varios componentes se puedan comunicar entre ellos, ya sea del padre hacia el hijo, del hijo hacia el padre o entre varios componentes, que no tienen necesariamente enlace de parentesco directo.

1. Pasar un dato del padre al hijo con ayudar de un input

Este método es la utilización simple de un input. El componente padre tiene una propiedad que va a transmitir al componente hijo, con ayuda de un input de este componente hijo.

Componente padre

@Component({  
    selector: 'app-parent',  
    template: `<div>  
        el padre tiene:   
        <pre>{{ data | json }}</pre>  
        <hr />  
        <!-- las propiedades del padre se pasan al componente hijo --> 
        <app-children [name]="name" [email]="email"></app-children> 
        </div>`,  
        styles:[`  
       :host{  
            display:inline-block;  
        }  
        hr{  
            width:100px;  
        }`]  
})  
export class ParentComponent {  
    name: string = "Parent";  
    email: string = "padre@angular.com";  
  
    get data(){  
        return { name: this.name, email: this.email };  
    }  
} 

El padre tiene dos propiedades: name y email.

Para una visualización única, un getterdata devuelve un objeto que contiene estas dos propiedades, para que podemos visualizarlas en JSON en una etiqueta pre, con ayuda del pipe json, integrado en Angular....

Los decoradores @ViewChild y @ViewChildren

Cuando es necesario manipular uno o varios componentes hijo, acceder a sus datos, modificarlos o llamar a sus métodos, es interesante llamar a los decoradores @ViewChild y @ViewChildren. Estos decoradores permiten hacer una “view query”, de manera que el localizador de cambios vaya a buscar el primer elemento que corresponda en el DOM.

1. Recuperar una referencia con @ViewChild

El decorador @ViewChild permite referenciar una instancia de un componente declarando una propiedad del tipo del componente hijo y después, decorándola con el decorador @ViewChild. El decorador recibe como argumento un tipo o una cadena de caracteres.

Especificando un tipo, es posible declarar el tipo de componente que queremos referenciar:

@ViewChild(ChildComponent)  
childrenComponent: ChildComponent; 

Especificando una cadena de caracteres, vamos a recuperar el componente (o el elemento, la directiva, etc.) que se referencia como variable local, con la clave correspondiente. A nivel del TypeScript tenemos:

@ViewChild('refChildren')  
childComponent: ChildComponent; 

Después, en el lado del template HTML:

 <app-children #refChildren></app-children> 

Como sucede con las variables locales, los decoradores @ViewChild y @ViewChildren no se limitan a los componentes, sino que también permiten recuperar las referencias del elemento (ElementRef), para acceder a sus propiedades.

Vamos a poder llamar a los métodos del componente hijo o acceder a sus atributos, porque el componente padre tiene una referencia al componente hijo, mediante la propiedad childComponent.

Tomemos un ejemplo completo. A continuación se muestra el contenido HTML del ChildComponent:

<div>  
 <input [(ngModel)]="text" placeholder="Texto del hijo"...

Los componentes Angular y la View Encapsulation

1. El Shadow DOM

Para poder entender el concepto de View Encapsulation (encapsulación de las vistas), es importante entender qué es el Shadow DOM. El Shadow DOM es una noción que proviene de los estándares de las Web Components, que permiten encapsular partes del DOM, así como los estilos.

Esto quiere decir que es posible limitar el campo de acción de un script o de un estilo, a un elemento concreto. Es posible aplicar estilos concretos a un único nodo del DOM, sin que el resto de la aplicación se vea afectada.

Es bastante obvio que esta noción es primordial para una aplicación que se construye centrada en componentes. Cada componente necesita su estilo particular, ya que sería molesto que el estilo definido para un componente se aplicara al resto de la aplicación.

Concretamente, con Angular, tomando el siguiente ejemplo de un template de componentes, así como el estilo de este, va a ser posible utilizar un simple selector, como encabezado o incluso p.paragraph. El estilo se aplica solo al componente en cuestión gracias al concepto del Shadow DOM. Esto es muy práctico, incluso esencial, cuando queremos utilizar componentes de terceros, que necesitan su propio estilo.

Template de un componente

<header>  
    Header  
</header>  
<section>  
    <h1 class="title">Título</h1>  
    <p class="paragraph">Texto del párrafo...</p>  
</section> 

Ejemplo de estilo

<style>  
    header {  
        font-size: 2em;  
        background: red;  
        color: #000;  
    }  
  
    section {  
        margin-top: 12px;  
    }  
  
   section h1 {  
        color: blue;  
    }  
  
    p.paragraph {  
        text-align: center;  
    }  
</style> 

O casi ... Es necesario saber que el Shadow DOM es una funcionalidad que aún...