(Part 2: Angular )Creé la misma app en React & Vue
Traducción del texto original de Sam Borick “I created the same app in React and Vue (Part 2: Angular)”
Después de crear la misma aplicación en React y Vue, ¡es justo que incluyamos Angular en la mezcla!
¿No has leído la Parte 1 todavía? Puedes revisarla aquí.
Uso Angular en el trabajo todos los días, pero en el mundo de JavaScript no se puede evitar escuchar sobre todos los otros marcos que hay. ¡También me encanta comparar manzanas con manzanas! Entonces, cuando vi el artículo de Sunil Sandhu sobre React vs Vue, ¡tuve que contactarme! Así que aquí estamos, React vs Vue vs Angular!
¿Cómo se ven todas las aplicaciones juntas?
Al igual que en la Parte 1, el css es casi idéntico a los otros dos, excepto donde están ubicados.
Esta aplicación Angular es generada por el CLI Angular (Interfaz de Línea de Comandos). Dado que Angular se reduce frecuentemente a ‘ng’, el comando para hacer esta aplicación fue ng generate ng-todo
.
En comparación con Vue y React, Angular tiene una tonelada de archivos. Una gran razón para esto es que mientras Vue pone todo para un componente en un archivo, y React divide el CSS en su propio archivo, Angular coloca el css en un archivo, html en otro y el código del componente en otro. Si bien podemos poner todo esto en un archivo, se considera la mejor práctica mantenerlos separados.
Otra razón para todos los archivos es que Angular usa TypeScript. TypeScript es “un superconjunto de JavaScript que proporciona tipografía estática, clases e interfaces opcionales”. Vamos a explicar un poco.
TypeScript es realmente simplemente agregar un montón de cosas en la capa superior de JavaScript. Si escribimos una línea de JavaScript en nuestro código de TypeScript, funcionará bien. Lo que TypeScript te permite hacer es crear clases fácilmente y hacer cumplir su uso.
En nuestro proyecto, hacemos una clase ToDo:
export class ToDo {constructor(item: string) {
this.Item = item;
}Item: string;
}
Esta clase no hace mucho por sí misma. Donde entra el poder es que podemos escribir funciones que requieren un ToDo, y el compilador de TypeScript nos gritará si intentamos y le damos algo más.
Por ejemplo:
function PrintToDo(myToDo: ToDo) { //the argument is of type ToDo
console.log(myToDo.Item)}//this will generate a compiler error
this.PrintToDo("not a ToDo type")//this will not
this.PrintToDo(new ToDo("a real ToDo"))
Por supuesto, podemos hacer esto con cualquier tipo que queramos, no solo con clases:
function PrintString(myString: string) {
console.log(myToDo)}//this will generate a compiler error
this.PrintToDo(new ToDo("not a string type"))//this will not
this.PrintToDo("A string!")
TypeScript es solo JavaScript, excepto que a veces producirá errores de tipeo y evitará errores tontos que se convertirían en errores en tiempo de ejecución en JavaScript.
A medida que una aplicación se vuelve más complicada, ¡clases como esta realmente son útiles! Sirven como un buen modelo para una cosa de la vida real, como un Producto, Trabajo o Persona. En el mundo angular, nos referimos a ellos como modelos.
¿Cómo creamos nuevos ToDos?
Aquí está nuestro ToDoComponent:
La mayoría de lo que sucede en este componente tiene que ver con el estilo y el formulario de entrada. Llegaremos a ellos en un momento, así que concentrémonos en la propia lista de tareas pendientes.
Cuando lleguemos a eso, nuestro componente de lista es solo una lista de ToDos! ngFor
puede tomar nuestra lista y mostrar cada elemento, como lo haría un foreach. ¡La gran diferencia aquí es que Angular manejará la actualización para nosotros! Cuando obtengamos una entrada válida, todo lo que tenemos que hacer es pasar la cadena a un nuevo objeto ToDo y agregarlo a nuestra lista. Angular se encarga del resto!
this.ToDos = this.ToDos.concat(new ToDo(this.Input));
¡Eso es todo! También es posible que queramos asegurarnos de que el usuario no envíe un ToDo vacío, así que, ¿cómo lo evitamos?
Validación de Formulario en Angular
En lugar de buscar presionar la tecla enter, o verificar el contenido de la cadena para que podamos lanzar un error, podemos usar Angular Forms para que lo haga por nosotros. Si nos fijamos en el ToDoComponent completo, declaramos un elemento form
,
<form (ngSubmit)="addItem()" #todoForm="ngForm">
El enlace ngSubmit
se activará cuando se presione el botón de envío, o el usuario presione enter! También se puede activar solo cuando el formulario está en un estado válido.
Un ngForm también crea una variable miembro de componente para cada entrada en un formulario, en este caso llamado name
. Podemos verificar en qué estado se encuentra esa entrada y mostrar errores u otros mensajes útiles dependiendo. En este caso utilizamosvalid
, pristine
y también de esta forma nos mantenemos al tanto de si el formulario se ha enviado anteriormente o no.
Dato curioso, también podemos escribir validadores personalizados para Angular! No los necesitamos aquí, pero podríamos tener un formulario que sepa cómo se debe formatear un número de teléfono, ¡y hacer toda la validación por nosotros! Limpio, ¿verdad?
Eso se ocupa de nuestra lista, pero ¿qué hay de mostrar realmente el ToDo?
Aquí está nuestro componente ToDo:
¿Cómo mutamos los datos?
En Angular, todo lo que tenemos que hacer para mostrar algunos datos son dos cosas:
- Tener un miembro en nuestro componente, en este caso ToDo.
- Referenciarlo en la plantilla con llaves {{ToDo.Item}}
¡Y eso es todo! Cuando cambiemos ToDo.Item, Angular actualizará la vista para nosotros. React no proporciona esos enlaces en realidad, porque llamar a setState volverá a representar el componente para nosotros de todos modos.
Comunicándose con los Componentes
Dado que este componente solo se ocupa de mostrar un solo ToDo, el ToDoComponent debe ser capaz de dar al componente ToDo Item un ToDo para mostrar. También debemos poder decirle a ToDoComponent que el usuario ha hecho clic en el botón “Eliminar”. Angular logra esto con ‘Entradas’ ‘Inputs’ y ‘Salidas’‘Outputs’.
Las entradas (‘Inputs’)son muy simples, pueden ser de cualquier tipo que queramos, y estarán vinculadas para nosotros! En este componente solo tenemos un ToDo como entrada. Le decimos a Angular que un miembro en particular es una entrada colocando el decorador @Input()
delante de él.
@Input() ToDo: ToDo = new ToDo("");
Entonces nuestro componente principal (Parent Componet)solo tiene que pasar el componente ToDoItem a ToDo como esto:
<ToDoItem [ToDo]=”ToDo”></ToDoItem>
Entonces solo usamos un enlace para mostrar nuestro ToDo!
Las salidas son un poco diferentes. Una salida no es solo algunos datos, también es un evento para activar lo que esté viendo esa salida. Los ‘Inputs’ en Angular pueden ser de cualquier tipo (como una cadena), pero las salidas deben ser del tipoEventEmitter
. Sin embargo, los EventEmitters emiten un valor que puede ser de cualquier tipo que queramos. Entonces, si quisiéramos generar una cadena, solo crearíamos un arreglo como este:
@Output() Example: EventEmitter<string> = new EventEmitter();
Y un componente padre puede suscribirse al evento de esta manera:
<ExampleComponent (Example)="exampleHandler($event)"></ExampleComponent>
Ahora que sabemos manejar las salidas ‘Outputs’ , ¿cómo eliminamos un ToDo?
Eliminar un ToDo
No necesitamos pasar nada de nuestro componente ToDoItem, solo tenemos que desencadenar un evento. Typescript necesita saber de qué tipo es nuestra salida, pero como no nos importa, simplemente la hacemos cualquiera any
, por lo que nuestra Salida se verá así:
@Output() Deleted: EventEmitter<any> = new EventEmitter();
Todavía tenemos que activar este evento dentro de ToDoItem. Tenemos un div bien formateado que parece un botón de la Parte 1, solo necesitamos conectar una función al evento de clic.
<div class="ToDoItem-Delete" (click)="deleteItem()">-</div>
Luego, deleteItem
llama a .emit()
en Deleted
:
deleteItem() {
this.Deleted.emit();
}
y Angular pasará el evento hasta ToDoComponent.
De vuelta en nuestro ToDoComponent, hemos vinculado la función deleteItem a nuestro componente ToDoItem. También le pasamos el índice del ToDo actual, por lo que sabemos cuál eliminar.
<div *ngFor="let ToDo of ToDos; index as i" >
<ToDoItem [ToDo]="ToDo" (Deleted)="deleteItem(i)"></ToDoItem>
</div>
Luego, todo lo que tenemos que hacer es eliminar el ToDo en ese índice, y Angular actualizará nuestra pantalla.
deleteItem(i: number) {
this.ToDos.splice(i, 1);
}
¡Aquí lo tenemos, una aplicación de lista de tareas pendientes!
Incluso una pequeña aplicación Angular tiene mucho más en juego que una aplicación React o Vue. Sin embargo, lo realmente bueno de Angular es que la mayor parte de la funcionalidad que necesita está dentro de Angular. Angular incluye enrutamiento de páginas, protección de acceso a las páginas, llamadas http, carga lenta del módulo y mucho más. Un marco pesado tiene una gran curva de aprendizaje. Sin embargo, la ventaja es que rara vez tengo que salir de Angular para encontrar una solución para lo que necesito. @mibzman
Github links:
- Angular ToDo: http://github.com/mibzman/ng-todo
- Vue ToDo: https://github.com/sunil-sandhu/vue-todo
- React ToDo: https://github.com/sunil-sandhu/react-todo
Texto Original
Part 1: Inglés — I created the exact same app in React and Vue. Here are the differences by @sunilsandhu
Part 2: Inglés — (Part 2: Angular)I created the same app in React and Vue by @mibzman