Arquitectura de Angular 2

Una aplicación Angular 2 se compone principalmente de las siguientes 8 partes:

  • 1. Módulos (Modules)
  • 2. Componentes (Components)
  • 3. Plantillas (Templates)
  • 4. Metadatos (Metadata)
  • 5. Enlace de datos (Data Binding)
  • 6. Directivas (Directives)
  • 7. Servicios (Services)
  • 8. Inyección de dependencias (Dependency Injection)

La siguiente figura muestra cómo funciona cada parte en conjunto:

En la figura, las plantillas (Templates) están compuestas por sintaxis HTML extendida por Angular; las clases de componentes (Components) se utilizan para gestionar estas plantillas; la parte de lógica de la aplicación se completa mediante servicios (Services); luego los servicios y componentes se empaquetan en módulos; finalmente, la aplicación se inicia arrancando el módulo raíz.

A continuación analizaremos las 8 partes anteriores por separado:


Módulos

Un módulo está compuesto por un bloque de código que puede utilizarse para realizar una tarea simple.

Las aplicaciones Angular son modulares y tienen su propio sistema de módulos: NgModules.

Cada aplicación Angular debe tener al menos un módulo (el módulo raíz), que generalmente puede llamarse AppModule.

Un módulo de Angular es una clase con el decorador @NgModule, que recibe un objeto de metadatos para describir las propiedades del módulo.

Varias propiedades importantes son las siguientes:

  • declarations (declaraciones)- Las clases de vista pertenecen a este módulo. Angular tiene tres tipos de clases de vista: componentes, directivas y pipes.

  • exports- Un subconjunto de declaraciones que se puede utilizar en las plantillas de componentes de otros módulos.

  • imports- Módulos con clases exportadas que se necesitan en las plantillas de componentes de este módulo.

  • providers- Creadores de servicios. Este módulo los añade a la tabla global de servicios para que puedan ser accedidos desde cualquier parte de la aplicación.

  • bootstrap- La vista principal de la aplicación, llamada componente raíz, es el anfitrión de todas las demás vistas de la aplicación. Solo el módulo raíz necesita establecer el atributo bootstrap.

Un módulo raíz muy simple:

Archivo app/app.module.ts:

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @NgModule({ imports: [ BrowserModule ], providers: [ Logger ], declarations: [ AppComponent ], exports: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }

A continuación, iniciamos la aplicación arrancando el módulo raíz. Durante el desarrollo, normalmente se arranca AppModule en el archivo main.ts, con el siguiente código:

Archivo app/main.ts:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app.module'; platformBrowserDynamic().bootstrapModule(AppModule);

Componentes

Un componente es una clase de control para una plantilla, utilizada para manejar la vista de la aplicación y la lógica de la página.

Los componentes son la base y el núcleo de las aplicaciones Angular y pueden utilizarse en toda la aplicación.

El componente sabe cómo renderizarse a sí mismo y cómo configurar la inyección de dependencias.

El componente interactúa con la vista a través de una API compuesta por propiedades y métodos.

Hay tres pasos para crear un componente Angular:

  • Importar el decorador Component desde @angular/core
  • Crear una clase normal y decorarla con @Component
  • En @Component, establecer el selectoretiqueta personalizada, y el templatePlantilla

Plantillas (Templates)

El lenguaje predeterminado de las plantillas Angular es HTML.

Podemos usar plantillas para definir la vista de un componente y así decirle a Angular cómo mostrar el componente. A continuación se muestra un ejemplo simple:

<div>
网站地址 : {{site}}
</div>

En Angular, por defecto se utilizan llaves dobles como sintaxis de interpolación; el valor entre las llaves suele ser el nombre de una variable de propiedad del componente.


Metadatos

Los metadatos le dicen a Angular cómo procesar una clase.

Consideremos que tenemos una clase llamada Component; es una clase hasta que le decimos a Angular que es un componente.

Puedes adjuntar metadatos a esta clase para decirle a Angular que Component es un componente.

En TypeScript, usamos decoradores para adjuntar metadatos.

Ejemplo

@Component({
   selector : 'mylist',
   template : '<h2>Ejemplo</h2>'
   directives : [ComponentDetails]
})
export class ListComponent{...}

El decorador @Component acepta un objeto de configuración y marca la clase que le sigue como clase de componente.

Angular crea y muestra el componente y su vista basándose en esta información.

Explicación de las opciones de configuración en @Component:

  • selector- Un selector CSS que le dice a Angular que busque una etiqueta <mylist> en el HTML del padre, cree el componente y lo inserte en esa etiqueta.

  • templateUrl- La dirección de la plantilla HTML del componente.

  • directives- Un array que contiene los componentes o directivas de los que depende esta plantilla.

  • providers- Un array que contiene los proveedores de inyección de dependencias necesarios para los servicios de los que depende el componente.


Enlace de datos (Data binding)

El enlace de datos proporciona a la aplicación una forma sencilla y consistente de mostrar datos e interactuar con ellos; es un mecanismo para gestionar los valores dentro de la aplicación.

Mediante este mecanismo, se pueden obtener y asignar valores desde el HTML, lo que hace que la lectura, escritura y persistencia de datos sean más simples y rápidas.

Como se muestra en la figura, la sintaxis del enlace de datos tiene cuatro formas. Cada forma tiene una dirección: desde el DOM, hacia el DOM, o bidireccional, como indican las flechas en la figura.

  • Interpolación: muestra el valor del componente en las etiquetas HTML.

    <h3>
    {{title}}
    <img src="{{ImageUrl}}.html">
    </h3>
    
  • Enlace de propiedades: establece la propiedad de un elemento como el valor de una propiedad del componente.

    <img [src]="userImageUrl">
    
  • Enlace de eventos: se activa cuando se hace clic y se llama al método del componente.

    <button (click)="onSave()">保存</button>
    
  • Enlace bidireccional: Usar la directiva NgModel de Angular permite realizar el enlace bidireccional de forma más conveniente.

    <input [value]="currentUser.firstName"
           (input)="currentUser.firstName=$event.target.value" >
    

Directivas

Las plantillas de Angular son dinámicas. Cuando Angular las renderiza, modifica el DOM según las directivas.

Una directiva es una clase con "metadatos de directiva". En TypeScript, se adjuntan los metadatos a la clase mediante el decorador @Directive.

En Angular existen los siguientes tres tipos de directivas:

  • Directivas de atributo: directivas que se utilizan como atributos de un elemento.
  • Directivas estructurales: se utilizan para cambiar la estructura del árbol DOM.
  • Componentes: como una subclase importante de las directivas, un componente puede considerarse esencialmente como una directiva con una plantilla.
<li *ngFor="let site of sites"></li>
<site-detail *ngIf="selectedSite"></site-detail>

*ngFor le dice a Angular que genere una etiqueta <li> para cada elemento de la lista sites.

*ngIf indica que el componente SiteDetail solo se incluirá cuando exista el elemento seleccionado.


Servicios

Un servicio en Angular 2 es un módulo independiente que encapsula una funcionalidad específica y puede ser utilizado por otros mediante inyección.

Los servicios se dividen en muchos tipos, incluyendo valores, funciones y características necesarias para la aplicación.

Por ejemplo, cuando aparece código repetido en varios componentes, se extrae el código repetido a un servicio para lograr la reutilización del código.

Los siguientes son algunos servicios comunes:

  • Servicio de registro
  • Servicio de datos
  • Bus de mensajes
  • Calculadora de impuestos
  • Configuración de la aplicación

El siguiente ejemplo es un servicio de registro que se utiliza para registrar mensajes en la consola del navegador:

export class Logger {
  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}

Inyección de dependencias

La inversión de control (Inversion of Control, abreviado IoC) es un principio de diseño en la programación orientada a objetos que se puede utilizar para reducir el acoplamiento entre el código de computadora. La forma más común se llama inyección de dependencias (Dependency Injection, abreviado DI), y también existe otra forma llamada "búsqueda de dependencias" (Dependency Lookup).

Mediante la inversión de control, cuando un objeto se crea, una entidad externa que controla todos los objetos del sistema le pasa la referencia de los objetos de los que depende. También se puede decir que las dependencias se inyectan en el objeto.

En el modelo de desarrollo tradicional, el llamador es responsable de gestionar las dependencias de todos los objetos, y las dependencias circulares siempre han sido una pesadilla. Sin embargo, en el patrón de inyección de dependencias, esta responsabilidad se transfiere al inyector (Injector), que se encarga de reemplazar los objetos dependientes en tiempo de ejecución, no en tiempo de compilación. Esta inversión de control y la característica de inyección en tiempo de ejecución son la esencia de la inyección de dependencias.

Angular puede determinar qué servicios necesita un componente examinando los tipos de parámetros del constructor. Por ejemplo, el constructor del componente SiteListComponent necesita un SiteService:

constructor(private service: SiteService) { }

Cuando Angular crea un componente, primero busca un inyector (Injector) para los servicios que necesita el componente.

El inyector es un contenedor que mantiene instancias de servicios y almacena las instancias creadas anteriormente.

Si el contenedor aún no tiene la instancia del servicio solicitado, el inyector crea una instancia del servicio, la agrega al contenedor y luego devuelve este servicio a Angular.

Cuando todos los servicios han sido resueltos y devueltos, Angular llama al constructor del componente con estos servicios como parámetros. Esto es la inyección de dependencias.

Otras extensiones