Gestión Dinámica de Tareas en JavaScript: Creación y Eliminación
Resumen
¿Cómo hacer la lista de tareas dinámica?
No basta con renderizar una lista de tareas, hay que hacerla dinámica para que actualice automáticamente cuando se agregan nuevos elementos. Comenzamos leyendo el input donde se introduce la nueva tarea. Implementaremos un método para capturar el cambio en el input y actualizar nuestro Array.
¿Cómo capturar los cambios en el input?
En el código, ya tenemos un input donde introducimos las tareas. Crearemos un método llamado chainHandler para recibir el valor que ingrese el usuario y almacenarlo en el Array.
functionchainHandler(event){let inputElement = event.target;let newTask = inputElement.value;// Implementar lógica para agregar nueva tarea en el Array}
¿Cómo agregar una nueva tarea a la lista?
Para incorporar la nueva tarea sin reiniciar la lista, usaremos Signals con el método update, que nos permite modificar o incluir un nuevo valor manteniendo los existentes:
El método update en Signals crea un nuevo estado sin mutar el anterior, clonando las tareas actuales y añadiendo la nueva al final. Esto es clave para manejar estados de forma efectiva.
¿Cómo eliminar tareas de la lista?
Eliminar un elemento de la lista también debe preservar el estado sin mutar el original, utilizando Signals y creando un nuevo estado.
¿Cómo implementar el método deleteTask?
Creamos un método que reciba la posición de la tarea a eliminar y use un filtro para crear un nuevo Array sin esa tarea:
Podemos probarlo ingresando nuevas tareas y eliminando las existentes en la aplicación para verificar cómo el estado de la lista se actualiza de forma dinámica y eficiente. Recuerda que mantener la interfaz y la lógica de la aplicación reactividad mejora la experiencia del usuario y facilita el manejo de estados a gran escala. ¡Sigue experimentando y aprendiendo!
Para que el input quede vacío al momento de agregar una tarea a la lista, solamente se agrega input.value='' en el método changeHandler() '; Quedando así:
mmmmm...pero al final no es muy practico que digamos
Es una buena practica tener la nomenclatura de camelCase para el nombre de las funciones, esto se relaciona con codigo limpio.
El método filter recibe una función de callback que puede tener hasta tres parámetros:
Elemento actual: Representa el elemento actual que se está evaluando en el array durante la iteración.
Índice: Representa el índice del elemento actual en el array durante la iteración.
Array original: (Opcional) Representa el array en el que se está iterando.
hola, entiendo ala perfeccion el video pero me genero una duda, la cual es ¿por que filter? y funciona con la misma lojica al traer la informacion desde una base de datos? (se que no han tocado temas de bases de datos pero me genero esa duda)
El asunto es que dentro del callback del metodo update(), retornes el nuevo valor; bien podrías usar filter como el video o splice como en los comentarios de arriba, podria ser otra opcion incluso
Y con las bases de datos ahi si depende del contexto, hay cosas que es mejor trabarlas en tu database, otras en tu back-end y otras en tu front-end! aunque casi no entendi la segunda pregunta
Creo que hay un error conceptual al hablar de inmutabilidad ya que al final el estado del array 'Tasks' si está mutando.
En este caso no hay diferencia entre utilizar el .update o .set.
deleteTask(index: number){this.tasks.set(this.tasks().filter((_, position)=> position != index));}
Me llevo que la eliminación de tareas se logra pasando el índice del elemento desde la interfaz al método correspondiente, usando filtros para construir un nuevo array sin la tarea seleccionada.
📍Inmutabilidad y manejo correcto del estado
Me llevo que tanto al agregar como al eliminar tareas es clave no mutar el array original, sino generar un nuevo estado, lo que hace que Angular detecte correctamente los cambios y renderice la vista.
📍Agregar tareas usando update en Signals
Me llevo que el método update de Signals permite agregar nuevas tareas al estado existente sin perder las anteriores, creando un nuevo array a partir del estado previo.
📍Capturar el valor del input
Me llevo que los cambios en el input se pueden capturar mediante un event handler, accediendo al event.target para obtener el valor ingresado por el usuario y usarlo en la lógica de la aplicación.
📍Hacer la lista realmente dinámica
Me llevo que una lista de tareas en Angular no solo debe renderizarse, sino ser dinámica, reaccionando automáticamente cuando se agregan o eliminan elementos a partir de la interacción del usuario.
Set basicamente destruye el valor actual del signal, con lo cual puedes asignar un valor completamente nuevo, que puede ser incluso de otro tipo de dato. El update te fuerza a mantener el mismo tipo de dato, aunque claro, puedes actualizar su valor.
Cual es la diferencia entre .update() y .set
es decir, esto tambien funciona:
this.tasks.set([...this.tasks(), newTask])
Set basicamente destruye el valor actual del signal, con lo cual puedes asignar un valor completamente nuevo, que puede ser incluso de otro tipo de dato. El update te fuerza a mantener el mismo tipo de dato, aunque claro, puedes actualizar su valor.
Una pregunta. ¿Cuál es la diferencia entre signal y NgModel y si la señal se puede usar en otro componente del proyecto?
La diferencia principal radica en cómo operan internamente: ngModel implementa un enlace de datos bidireccional (two-way data binding), mientras que signal ofrece soporte a una reactividad más detallada y granular. A pesar de esto, para la gestión de formularios y campos, mi preferencia se inclina hacia el uso de ReactiveForms. Es importante destacar que en versiones futuras de Angular, se espera que la reactividad en los formularios también se pueda manejar a través de signals.
Hola estoy obteniendo este error cuando quiero usar *ngFor
Can't bind to 'ngForOf' since it isn't a known property of 'li' (used in the '_HomeComponent' component template).
A alguien mas le sucedio que me pueda ayudar?
Realmente tocaría ver más del código, si puedes compartir el repo o la lógica del HTML y TS, con eso podría ser de más ayuda
Ya pude resolverlo, es que esta usando una versión muy vieja de Angular. Gracias
Cual sería la diferencia de usar en signal .update o .set?
es decir en ese caso yo podria poner:
this.tasks.set([...tasks, newTask])
o también podria poner
this.tasks.update((tasks) => [...tasks, newTask])
hay alguna diferencia en terminos de rendimiento?
Las dos opciones que mencionas, lamentablemente, no son viables en este contexto. El problema radica en que al utilizar […tasks, newTask], no tienes acceso directo a tasks, ya que tasks es un 'signal', no el array de tareas en sí. Una alternativa sería usar […this.tasks(), newTask], pero esta no es la mejor solución. En cambio, te recomiendo emplear el método update. Con update, puedes obtener el valor actual y, a partir de ahí, agregar la nueva tarea de manera más eficiente y adecuada a la estructura del código.
Tengo una duda en mi caso para el tema de agregar una nueva tarea de estas formas y ambas funcionaron:
La duda es hay alguna problema en este caso
this._tasks().push(this.createTask(input.value));
El problema es que estarías mutando el estado (es decir el array), cosa que no es recomendada en general en JS y en los patrones de manejo del estado. La buena práctica siempre es hacer "un clon" del estado, modificar ese clon y retornar un nuevo estado. Adicional comienzas a mezclar cosas que te complican el mantenimiento de la aplicación, porque si la misma API de Signal nos ofrece un método para actualizar su valor y no lo usamos, sino que nos basamos en el valor que nos retorna la signal (this._task() ) para actualizarlo entonces ya el mantenimiento del estado se lo estamos dando nosotros y no el framework.