viernes, 30 de diciembre de 2016

Angular 2. Formularios. Entrega 5: Templates (4). Directivas

Anteriormente en la versión 1 de Angular, había más de 70 directivas, además la comunidad contriubuyó con muchísimas más. Pero se cree que no hace falta tantas directivas. Veamos las más importantes:

1. NgClass vs class binding

Es la mejor opción para agregar o quitar clases CSS dinámicamente.

Veamos el primer ejemplo donde utilizamos class binding en vez de NgClass, para modificar una sola clase.

!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>
En cambio con NgClass, podemos asignar varia clases a la vez. Veamos la función setClasses() que da varios valores de clase:

setClasses() {
  let classes =  {
    saveable: this.canSave,      // true
    modified: !this.isUnchanged, // false
    special: this.isSpecial,     // true
  };
  return classes;
}
Y en el template las podemos utilizar con NgClass:
<div [ngClass]="setClasses()">This div is saveable and special</div>

2. NgStyle vs style binding

Al igual que antes, vemaos un ejemplo de style binding, donde solo podemos assignar un estilo a la vez
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
  This div is x-large.
</div>
En cambio con NgStyle podemos asignar varios estilos a la vez, como en el ejemplo anterior, creamos en el componente, una variable de tipo estructura que tenga los siguientes atributos, font-style, font-weight y font-size, y mediante el operador ":" les asignamos valores mediante el operador ternario (condicion ? valor_si_se_cumple : valor_si_no_se_cumple)

setStyles() {
  let styles = {
    // CSS property names
    'font-style':  this.canSave      ? 'italic' : 'normal',  // italic
    'font-weight': !this.isUnchanged ? 'bold'   : 'normal',  // normal
    'font-size':   this.isSpecial    ? '24px'   : '8px',     // 24px
  };
  return styles;
}
Y ahora en el template asignamos varios estilos a la vez.

<div [ngStyle]="setStyles()">
  This div is italic, normal weight, and extra large (24px).
</div>

3. NgIf vs visibilidad con clases y estilos

Hasta ahora, las directivas NgClass, NgStyle, se trascribían [ngClass ] y [ngStile] en el template , pero la directiva NgIf se escribe *ngIf en el template, y no nos olvidemos del asterisco.

Si queremos quitar elementos (y sus hijos)del DOM, utilizaremos NgIf, pero si no los queremos quitar pero si ocultar (hacerlos invisibles) podemos aplicar una clase o estilo invisible.
<div *ngIf="currentHero">Hello, {{currentHero.firstName}}</div>
Aquí si no existe currentHero, no muestra nada. Veamos otro ejemplo:
<!-- because of the ngIf guard
    `nullHero.firstName` never has a chance to fail -->
<div *ngIf="nullHero">Hello, {{nullHero.firstName}}</div>

<!-- Hero Detail is not in the DOM because isActive is false-->
<hero-detail *ngIf="isActive"></hero-detail>
Pero codemos ocultarlo (y no eliminarlo del DOM con clases)
<!-- isSpecial is false -->
<div [class.hidden]="!isSpecial">Show with class</div>


4. NgSwitch (cuidado con los *)

Es similar a la anterior, pero cuidado con los asteriscos y corchetes, ya que se utilizan 3 subdirectivas

1. [ngSwitch]
2. *ngSwitchCase
3. *ngSwitchDefault

Veamos un ejemplo en el template:
<span [ngSwitch]="toeChoice">
  <span *ngSwitchCase="'Eenie'">Eenie</span>
  <span *ngSwitchCase="'Meanie'">Meanie</span>
  <span *ngSwitchCase="'Miney'">Miney</span>
  <span *ngSwitchCase="'Moe'">Moe</span>
  <span *ngSwitchDefault>other</span>
</span>

5.NgFor e índices. Problemas de rendimiento.

Sirve para hacer repeticones. Se puede aplicar a un simple div o a un componente:

div *ngFor="let hero of heroes">{{hero.fullName}}</div>
<hero-detail *ngFor="let hero of heroes" [hero]="hero"></hero-detail>
OJO: Con el let hero del for creamos una variable de entrada del template, que NO es lo mismo que una variable de referencia del template

Tenemos las siguientes variables dentro del bucle NgFor:
1. index: Contador desde 0 en el bucle
2. first: si es el primero
3. last: si es el último
4. even: si es par
5. odd: si es impar

Aquí mostramos el nombre del héroe y sumamos 1 para que nos muestre el contador desde 1 y no desde 0:
<div *ngFor="let hero of heroes; let i=index">{{i + 1}} - {{hero.fullName}}</div>
Pueden surgir problemas de rendimiento, normalmente en listas largas. Una inserción o remoción de un elemento, puede disparar manipulaciones del DOM en cascada.
Si pedimos otra vez la lista de heroes desde el servidor, borra la lista antigua y la sustituye por la nueva. En cambio, si le aportamos una función que le indica que un héroe es el mismo si tiene el mismo id, entonces, angular no borrara los cambios efectuados desde el último refresco.

Veamos la función
trackByHeroes(index: number, hero: Hero) { return hero.id; }
Y también como utilizarla en el template con la clausula trackBy:
<div *ngFor="let hero of heroes; trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>




No hay comentarios :

Publicar un comentario