Tribalyte Technologies Tribalyte Technologies
  • Inicio
  • Misión y visión
  • Nuestros expertos
  • Nuestras soluciones
  • Casos de éxito
  • Blog
  • Contáctanos
  • Únete al equipo
Tribalyte Technologies Tribalyte Technologies
  • Inicio
  • Misión y visión
  • Nuestros expertos
  • Nuestras soluciones
  • Casos de éxito
  • Blog
  • Contáctanos
  • Únete al equipo
Nov 21

Introducción a NgRx

  • noviembre 21, 2019
  • José Luis Coalla
  • No Comments
  • Consejos tecnológicos, Desarrollo de software

La semana pasada escribimos un post sobre Redux y conocimos las diferentes partes que lo forman: Store, Actions y Reducers. En este post realizaremos una pequeña introducción a NgRx, un framework para introducir el flujo de desarrollo Flux a una aplicación Angular. Si quieres echarle un vistazo a las nociones básicas de Redux antes de lanzarte con esa introducción, pulsa aquí para ir al anterior post.

Ahora explicaremos paso a paso cómo hacer un ejemplo simple, pero práctico, para empezar a utilizar NgRx.

1 – Instalación

Empezaremos creando un proyecto de Angular nuevo e instalando el paquete @ngrx/store a través de npm

  • ng new ngrx-tri-training
  • npm install –save @ngrx/store


Si queremos cerciorarnos de que el proyecto se ha creado correctamente, siempre podemos ejecutarlo e iniciarlo en nuestro navegador

  • npm start -> localhost:4200


Si todo es correcto, deberíamos ver la landing page básica de Angular dependiendo de la versión de Angular-CLI que tengamos instalada.

2 – Crear Modelo

En este tutorial vamos a crear una aplicación para leer, crear y eliminar “links”. Así que empezaremos creando un modelo de “Link”, que estará formado por un nombre y una url.

src/app/models/link.model.ts


export interface Link {

name: string;

url: string; 
}

3 – Crear Acción

Ahora crearemos las acciones. Como vimos en la introducción del blog anterior, las acciones son objetos que nos describen lo que está ocurriendo. En nuestro caso, para que sea más fácil identificarlos, crearemos una clase para cada acción y tener así un tipado más claro.

src/app/actions/link.actions.ts

import { Action } from "@ngrx/store";
import { Link } from "../models/link.model";
 
export const ADD_LINK = "[LINK] Add";
export const REMOVE_LINK = "[LINK] Remove";
 
export class AddLink implements Action {
  readonly type = ADD_LINK;
  constructor(public payload: Link) { }
}
export class RemoveLink implements Action {
  readonly type = REMOVE_LINK;
  constructor(public payload: number) { }
}
 
export type Actions = AddLink | RemoveLink

 

Hay que destacar que cada acción tiene un tipo “type” que describe la acción, y un “payload” con los datos de dicha acción. Recordad que el payload puede ser opcional dependiendo de la acción.

4 – Crear Reducers

Después, necesitaremos un reducer que trate la acción y nos devuelva el estado deseado tras dicha acción.

src/app/reducers/link.reducer.ts

import { Action } from "@ngrx/store";
import { Link } from "../models/link.model";
import * as LinkActions from "../actions/link.actions";
 
const initialState: Link = {
   name: "Google Link",
   url: "http://google.com"
}
 
export function reducer(state: Link[] = [initialState], action: LinkActions.Actions) {
 
   switch (action.type) {
       case LinkActions.ADD_LINK:
           return [...state, action.payload];
       default:
           return state;
   }
}

Como vemos en el código, dependiendo del tipo de la acción lanzada, el reducer decidirá cómo tratar los datos.

En este caso, y para mejor visualización de los datos en el ejemplo que veremos en un rato, se inicializa el “state” con un link predefinido. Esto no es necesario ya que normalmente inicializamos este estado a través de otros canales más convencionales; como podría ser un API.

5 – Crear AppState

src/app/app.state.ts

import { Link } from "./models/link.model";
 
export interface AppState {
   readonly links: Link[];
}

Es importante que tengamos en cuenta que hemos denominado “links”, a la clave que contendrá toda la información de los links, ya que lo utilizaremos a continuación.

6 – Actualizar AppModule

src/app/app.module.ts

// Other imports
import { StoreModule } from "@ngrx/store";
import { reducer } from "./reducers/link.reducer";
 
@NgModule({
 // Other code
 imports: [
   BrowserModule,
   StoreModule.forRoot({
     links: reducer
   })
 ],
 // Other code

Ahora introducimos el “StoreModule” en el módulo de la aplicación, y asociamos el reducer creado anteriormente a la clave “links” que hemos creado en el punto anterior, de ahí su importancia.

7 – Crear Componentes

  • ng g c components/read
  • ng g c components/create


Ahora crearemos dos nuevos componentes; read y create.

Dependiendo del Angular-cli que utilicéis, se nos añadirán directamente al archivo “app.module.ts”. En caso de que no se nos añadan, lo haremos manualmente.

8 – Leer de la store

Tras esto, vamos a modificar el componente “read” para mostrar los datos que tengamos en la store.

src/app/components/read/read.component.ts

import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs";
import { Store } from "@ngrx/store";
import { Link } from "./../../models/link.model";
import { AppState } from "./../../app.state";
 
@Component({
   selector: "app-read",
   templateUrl: "./read.component.html",
   styleUrls: ["./read.component.scss"]
})
export class ReadComponent implements OnInit {
 
   public links: Observable<Link[]>
 
   constructor(
       private store: Store<AppState>
   ) {
       this.links = store.select("links");
   }
 
   ngOnInit() {
   }
 
}

Nos crearemos una variables “links” que sera un observable de array de “Link”. En esta variable guardaremos los datos de los links guardados en la store a través de la funcion “store.select()”. Es importante también ver que a esta función le hemos pasado el literal “links”, que es el mismo nombre que le dimos a la clave en AppState y al objeto pasado al StoreModule en el archivo “app.module.ts”.

src/app/components/read/read.component.html


<div *ngIf="links">
 

<h3>Links</h3>


<ul>

<li *ngFor="let link of links | async">
           <a [href]="link.url" target="_blank">{{ link.name }}</a>
       </li>

   </ul>

 
</div>

Por otra parte, en el archivo .html del componente, creamos una lista simple de todos los links guardados. Lo más importante de este *ngFor es el pipe “| async”, que identificara los cambios en el state automáticamente y cambiara la lista de forma acorde.

src/app/app.component.html

<app-create></app-create>
<app-read></app-read>

Por ultimo, modificamos todo el archivo “app.component.html” e introducimos los tags de los nuevos componentes creados. Si todo funciona correctamente, deberíamos ver la lista inicializada de links.

Tribalyte-links-google link

 

 

 

 

9 – Escribir en la Store

src/app/components/create/create.component.ts

import { Component, OnInit } from "@angular/core";
import { Store } from "@ngrx/store";
import { AppState } from "./../../app.state";
import { Link } from "./../../models/link.model"
import * as LinkActions from "./../../actions/link.actions";
import { Observable } from "rxjs";
 
@Component({
 selector: "app-create",
 templateUrl: "./create.component.html",
 styleUrls: ["./create.component.scss"]
})
export class CreateComponent implements OnInit {
 
 constructor(
   private store: Store<AppState>
 ) { }
 
 ngOnInit() {
 }
 
 public addLink(name: string, url: string) {
   this.store.dispatch(new LinkActions.AddLink({ name: name, url: url }));
   // this.store.dispatch({ type: LinkActions.ADD_LINK, payload: { name: name, url: url } });
 }
 
}

src/app/components/create/create.component.html





<div>
   <input type="text" placeholder="name" #name>
   <input type="text" placeholder="url" #url>
 
   <button (click)="addLink(name.value, url.value)">Add a Link</button>
</div>




Ahora empezaremos a añadir links a la store. Para ello creamos dos input que tomen el nombre y la url del link, y pasará esos datos al componente con la función “addLink()”.

En el componente, con esos datos, disparamos la acción a través del método “store.dispatch()”. Como se ve en el código, a este distpatch le pasaremos la acción, que tiene un tipo inferido y el payload con los datos de el link. Más tarde el reducer reconocerá el tipo, y añadirá el nuevo link al array de la store.

Tribalyte-links-google link

10 – Borrar de la store

Por último vamos a añadir la posibilidad de borrar links de la lista. Para ellos crearemos una función que, a través del index de la lista, obtenga el link seleccionado y lo borre de esta.

src/app/components/read/read.component.html




<li (click)="deleteLink(i)" *ngFor="let link of links | async; let i = index">

src/app/components/read/read.component.ts

import * as LinkActions from "./../../actions/link.actions";
 
p
ublic deleteLink(index: number) {
       this.store.dispatch(new LinkActions.RemoveLink(index));
}


Al igual que en el caso de añadir libros, lanzaremos una acción, pero en este caso con el nuevo tipo y un payload diferente.

src/app/reducers/link.reducer.ts

       case LinkActions.REMOVE_LINK:
           state.splice(action.payload, 1);
           return state;


Hay que recordar añadir el nuevo tipo en el reducer, para que este pueda tratar los datos cuando se lanze la acción con el tipo “REMOVE_LINK”.

Si se ha realizado todo correctamente, una vez añadido un link, podremos eliminarlo de la lista tocando en cualquier parte de la columna en la que está escrito el link. Si clicamos en el link, este se abrirá en una pestaña nueva, así que recordad clicar a la derecha de este.

Conclusiones

Como hemos podido ver, se trata de un tutorial bastante sencillo en el que vemos una idea general de cómo funciona NgRx, este framework de Angular.

En un aplicación real deberíamos conectar este estado a una base de datos, y cargar todos los datos a través de una API. Os animo a que investiguéis más sobre esta librería en la documentación aquí.

Espero que este tutorial de NgRx os aclare algunas idea y os haya gustado. Si tenéis alguna consulta, no dudéis en preguntar.

¡Un saludo!

Artículos Relacionados:

  • Pruebas extremo a extremo en Angular con CucumberPruebas extremo a extremo en Angular con Cucumber
  • image3Ejemplo práctico con Appium: App móvil híbrida
  • Depurando apps creadas con Ionic 3.xDepurando apps creadas con Ionic 3.x
  • Expertos en desarrollo app de salud en Madrid y toda España7 recomendaciones para desarrollar la App de Salud perfecta
  • Fissios-appFissios para pacientes de COVID-19
  • Facebook
  • Twitter
  • LinkedIn
  • E-Mail

About The Author

José Luis es Ingeniero de Software. Su trabajo en Tribalyte se centra en el desarrollo web, específicamente en el desarrollo de aplicaciones híbridas full stack. Le encantaría dominar la utilización de frameworks como Angular e Ionic. Apasionado de las nuevas tecnologías, de aprender cada día algo nuevo y de aprovechar cada momento al máximo.

Leave a reply Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

ELIGE UNA CATEGORÍA

  • Blockchain
  • Consejos tecnológicos
  • Desarrollo de aplicaciones
  • Desarrollo de software
  • Sistema embebido
  • Tecnologías

Suscríbete a nuestra newsletter y entérate de las últimas tendencias tecnológicas.

Una compañía dedicada al desarrollo y la mejora de plataformas tecnológicas globales.

SOCIOS

Contacto

Glorieta de Quevedo 8 6º2
28015 Madrid (ESPAÑA)
Phone: +34 910 177 514 E-Mail: contact@tribalyte.com Web: www.tribalyte.com

AYUDA

  • Política de privacidad
  • Política de calidad
  • Términos de uso

CERTIFICACIONES

INTERNACIONALIZACIÓN

  Tribalyte     Technologies S.L. en   el Marco del Programa de Iniciación a la Exportación del Prog. ICEXNEXT, ha contado con el apoyo del ICEX y con la cofinanciación del fondo Europeo FEDER. La finalidad de este apoyo es contribuir al desarrollo Internacional de la empresa y de su entorno.
Esta página web utiliza cookies para mejorar su experiencia de usuario y para recabar estadísticas anónimas de uso. Aceptar Más información