IIIa. Angular 4 Openwebinars
Contingut
Usaremos Angular CLI para crear nuestra aplicación, ejecutando en consola los comandos
- Generar un componente:
$ ng generate component nombre
o
$ ng g c nombre
Interpolación y property data binding
Live Databinding
Cuando el valor cambia en el componente, automáticamente se refleja en el template.
El flujo de información es: ocurre algo en el componente y queremos que el template lo refleje automáticamente.
Con sintaxis así, con el nombre de interpolación:
property="{{value}}" // <img src="{{url}}">
O así, con el nombre de property data binding:
[property]="value" // <img [src]="url">
Los valores de las propiedades pueden ser variables del componente o llamadas a métodos.
En concreto es un lenguaje de expresiones, que es evaluado y transformado a cadena.
Podemos hacer
textContent={{1 + 1 + getVal()}}
No se permite efectos secundarios (assignments, new(), ‘;’, ++). No sabemos cuantas veces se van a evaluar. Los cálculos o llamadas deberían ser rápidas, simples y siempre devolver lo mismo (sin estado mutable).
No se permite usar el namespace global (Math, window.)
Ejemplos de sintaxis
disabled={{expression}} == [disabled]=”expression”
<p [textContent]="user.name"> == <p>{{user.name}}
<img [src] = "url">
<app [talk]="talk"></app>
<div [ngClass] = "{selected: isSelected}"></div>
<button [style.color] = "isSpecial ? 'red' : 'green'">
<div [class.special]="isSpecial">Special</div>
Propiedades DOM vs attributos HTML
Los atributos HTML inicializan propiedades DOM cuando la web se carga. Luego ya no cambian. Por JS podemos cambiar la propiedad DOM.
Angular (2,4,…) trabaja a nivel de propiedades DOM salvo:
- Atributos sin propiedades DOM: colspan, atributos de aria (accesibilidad).
Interpolación de estilos
Con sintaxis específica:
[style.color]="method(value)" // devolviendo 'red' [style.color]="propiedad" // devolviendo 'red' [style.background-color]="propiedad"
O referenciar a un objeto completo:
[ngStyle] = "propiedad" // {'background-color': 'red'}
Event binding
El flujo complementario al de interpolación: ocurre algo en el template y queremos que el componente lo sepa.
La sintaxis es con paréntesis (DOM_EVENT)=”METODO_EN_EL_COMPONENTE”
HTML:
<button (click)="onClickMe()">fav</button>
Javascript:
onClickMe() {
console.log('click!')
}
Podemos pasar variables y constantes al método llamado:
<button (click)="onClickMe('valor', variable)">fav</button>
Y podemos referenciar todo el elemento del DOM que originó el event binding con la variable $event
<button (click)="onClickMe($event)">fav</button>
Eso imprime un evento del DOM, en este caso click. Por la referencia del evento del DOM, en target.value está el valor del input que originó el evento. Por lo que podríamos leer el valor accediento a $event.target.value.
Local template identifier
Con la sintaxis de corchete (#) podemos definir variables en nuestro template, que apuntan al elemento del DOM en el que definimos las variables:
<input #search (keyup)="onKey(search.value)">
Template statements
- Soportan efectos secundarios (es dónde deberíamos hacerlos, no en la interpolación)
- Soporta ; y asignaciones
- No soporta new(), ++, +=, console.log or pipes
Directivas
Componente sin template anotadas con @Directive
Hay varios tipos de directivas pero en general vamos a utilizar directivas estructurales, que manipulan el template de un componente. Ya sea repitiéndolo (ngFor) o mostrándolo o no (ngIf).
*ngFor
Para iterar elementos (arrays, iterables…)
<div *ngFor="let talk of talks">
{{talk.title}}
</div>
Hay variables para acceder a propiedades útiles de nuestro array:
- index
- odd
- even
- first
- last
- trackby (para reciclar filas por rendimiento)
<div *ngFor="let talk of talks;let i = index;let odd = odd;let first = first"> </div>
*ngIf
Elimina del DOM
Totalmente distinto de cambio de visibilidad a hidden/visible, *ngIf elimina del árbol DOM el componente (no aparece si hacemos view source).
<div *ngIf="PROPIEDAD_DEL_COMPONENTE"> </div>
Comunicación entre componentes: Inputs y Outputs
Angular está basado en una jerarquía de componentes basada en el selector (especificado en el componente y usado en el template).
Tenemos que hacer componentes pequeños que se comunican entre sí.
Inputs
Comunicación de un componente padre a otro componente hijo, la sintaxis es:
En el template padre:
<component-hijo [nombre_variable]="valor" />
En el componente hijo:
@Input() nombre_variable
Es la misma sintaxis que el property data binding!.
Es importante comentar que los inputs NO se evalúan en el constructor, lo hacen después de haberse construido el componente.
Podemos leerlo en el método ngOnInit
Outputs
Comunicación hijo -> padre. Transmitimos información de un componente hijo a su padre, a través de eventos.
La sintaxis es:
En el componente hijo:
@Output() nombre_variable = new EventEmitter<any>()
Y cuando se origine el evento, también en el componente hijo:
this.nombre_variable.emit(VALOR)
En el template padre:
<component-hijo (nombre_variable)=metodo($event) />
Y en el componente padre:
metodo(evento) {...}
El flujo es más complicado porque definimos un Output, emitimos el evento (cuando suceda lo que queremos emitir, un click, mouseover…) y en el template padre escuchamos con ().
Es la misma sintaxis que el event binding!.
creat per Joan Quintana Compte, març 2019