En este punto deberías saber ya cómo se crean los Componentes en Angular y como se añaden a las rutas mediante El router de Angular.
Como ya hemos hablado, los componentes de Angular están formados por 3 archivos (el .html, el .ts y el .css o .scss). Precisamente en el artículo de hoy vamos a echar un vistazo al archivo .html, es decir, al que contiene la vista o el template del componente.
En estos archivos puedes escribir código HTML como has hecho siempre y también varias etiquetas especiales que ahora veremos.
Cómo crear variables en Angular
Debajo del export se crean las variables con su tipo de dato y así aprovechamos la funcionalidad de typescript. Dentro del constructor se inicialzan las variables con un valor por defecto.
// example.component.ts
export class ExampleComponent implements OnInit {
exampleString: string;
exampleArray: string;
constructor() {
this.exampleArray = [];
}
ngOnInit() {}
}
Las variables las puedes llamar como quieras, aunque yo siempre recomiendo que sea en camelCase (la primera letra en minúsculas y cada palabra a continuación con mayúsculas).
Otro punto importante que tienes que saber respecto a las variables es que son reactivas, eso quiere decir que una vez cargado el componente, si cambias el valor de una variable, en la vista se va a actualizar sin que tengas que hacer nada.
Veamos ahora como se muestran las variables en la vista.
La manera más rápida de mostrar una variable definida en un controlador (fichero .component.ts) es usar la sintaxis:
<p>{{ exampleString }}</p>
Lo bueno de esta sintaxis es que dentro de las dos llaves el código se ejecutará como si fuera de Javascript, es decir, puedes hacer:
<span>La suma de 5 y 4 es {{ 5 + 4 }}</span>
O por ejemplo llamar a un método definido en el controlador:
<p>{{ getVal() }}</p>
O concatenar strings:
<p>{{ exampleString1 + "-" + exampleString2 }}</p>
y ponemos un input junto a un botón para mostrarlas: O incluso fechas:
<p>{{ new Date() }}</p>
ngFor para mostrar listas de elementos
¿Qué pasa si tenemos un array de información?, para este caso Angular viene con etiquetas especiales para recorrer arrays o listas:
<ul>
<li *ngFor="let item of listVariable">{{ item }}</li>
</ul>
Es importante poner el * antes del ngFor para que Angular lo detecte adecuadamente.
Como ves, dentro del ngFor usamos sintaxis ES6, en concreto hacemos un for each. Es decir, dentro del ngFor se crea la variable item que en cada iteracción del bucle actualizará su valor por el valor en ese momento.
Cuando Angular sirva la página se encargara de crear un elemento <li>
por cada elemento del array, y dentro de cada uno, mostrará su contenido. Si en lugar de hacer el ngFor dentro un <li>
lo haces dentro de un <div>
, por ejemplo, se creará un div por cada elemento del array.
Puedes incluso hacer estructuras más complejas y concatenar bucles:
<ul>
<li *ngFor="let item of listVariable">
<li *ngFor="let subitem of item">
<p>{{ subitem }}</p>
</li>
</li>
</ul>
¿Y si el array es un array de objetos, como se muestran los atributos de los objetos?
Simplemente al mostrar los elementos del array puedes usar la notación punto para acceder a sus propiedades:
{{ item.atributo }}
Por cierto, si necesitas el número del índice que se está recorriendo (para la primera iteracción 0, para la segunda 1...) puedes hacer:
<ul>
<li *ngFor="let item of nombre_array; let i = index">{{i}}. {{ item }}</li>
</ul>
ngIf para mostrar elementos de forma condicional
En ocasiones, necesitamos que un elemento se muestre en pantalla dependiendo de una condición. Esto se consigue por medio de ngIf:
<div *ngIf="array.length > 3">
Esto se muestra si el array tiene menos de 3 elementos
</div>
Si por ejemplo, tenemos una variable boolean (true, o false) definida en el controlador, también podemos motrar contenido o no dependiendo del valor de esa variable:
<div *ngIf="condicion">
Esto se muestra si la variable condicion es true (o distinto de null y
undefined)
</div>
De esta forma, por ejemplo, podemos mostrar en el navbar, un botón de login si el usuario no está registrado:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarTogglerDemo03"
aria-controls="navbarTogglerDemo03"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarTogglerDemo03">
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="#"
>Home <span class="sr-only">(current)</span></a
>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<div class="form-inline my-2 my-lg-0" *ngIf="!userIsLogged">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">
Login
</button>
</div>
</div>
</nav>
Si te das cuenta, he puesto el ! antes de la variable de userIsLogged para negarlo, es decir, si el usuario no está registrado se mostrará el botón de login.
Dentro de los if también podemos llamar a funciones dentro de su controlador, por ejemplo:
<div *ngIf="getVal() < 3">Ejemplo</div>
En este caso el string "Ejemplo" solo se mostrará si el valor de returno de la función getVal definida en el controlador es mayor a 3;
Estilos y atributos del HTML dinámicos
Puedes hacer bind, es decir, hacer que un atributo del HTML tenga el valor de una variable definida en el controlador.
Por ejemplo:
<img [src]="imagePath" />
En este caso el valor src de la imagen tendrá el valor que tenga esa variable en ese momento.
Si queremos, por ejemplo, cambiar el color de fondo de una etiqueta html, pero poniendo el color que tenemos guardado en una variable, se hace así:
<div class="circle" [style.background]="color"></div>
Como puedes observar, para los atributos de las etiquetas html se hace poniendo el atributo entre corchetes, y para los estilos también, solo que añadiendo style delante.
Binding de click y para los inputs
Por ejemplo para controlar cuándo el usuario hace click en un botón:
<button (click)="onClick()">Click me!</button>
Es decir, este tipo de eventos va entre paréntesis. Después en el controlador, tenemos que crear un método con el mismo nombre, en este caso, onClick, que será la que se ejecute al pulsar el botón.
// button-example.component.ts
export class ExampleComponent implements OnInit {
exampleString: string;
exampleArray: string;
constructor() {
this.exampleArray = [];
}
ngOnInit() {
}
onClick(){
console.log("Botón pulsado").
}
}
Recoger el valor en los inputs
También puedes almacenar el valor que escribe el usuario en los recuadros input de HTML.
Para recoger el valor del input mientras escribe el usuario, antes tenemos que asegurarnos que hemos importado el módulo de FormsModule de Angular, en el archivo app.module.ts, es decir:
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, FormsModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Una vez hecho esto podemos continuar creando los inputs. Para bindear el input con la variable:
<input [(ngModel)]="name" />
El ngModel con esa sintaxis lo tienes que poner siempre, pero name en este ejemplo es una variable que he creado en el controlador (archivo .component.ts de ese componente). Ahí puedes poner el nombre que quieras siempre y cuando tengas una variable que se llame igual.
Para recordar esta sitaxis se suele usar la regla memotécnica de la caja de bananas [()].
Al usar la sintaxis [(...)] lo que estamos haciendo es two way data binding. El paso de información se hace en dos sentidos: entre el html y el controlador y al revés.
Esto quiere decir que si actualizamos el valor en el html o en el controlador en el otro sentido se actualizará automáticamente.
Si ahora muestras la variable name, debajo del input, te darás cuenta de que según escribes en el formulario se va mostrando abajo automáticamente:
<input [(ngModel)]="name" />
<p>{{ name }}</p>
Para elementos de formulario, te recomiendo también que mires técnicas más avanzadas como usar los FormControl y FormGroup de Angular.
Conclusiones
Ahora que sabes usar todo el sistema de vistas en Angular, echa un ojo a el Ejemplo práctico de web de notas en Angular para que pongas en práctica estos conocimientos.
También puedes mirar ya la Comunicación entre componentes en Angular para poder pasar parámetros a componentes hijos.