Al igual que con un If, Angular permite iterar un array de números, de cadenas de caracteres o de objetos usando "*ngFor".Si tienes en tu componente un array de datos:
Puedes mostrar cada elemento iterando el array en un elemento HTML:
<ul><li *ngFor="let str of myArray">{{ str }}</li></ul>
El *ngFor crea una variable temporal llamada str (o el nombre que más te guste) que contiene cada valor de myArray. Finalmente, utilizando una interpolación, muestras el valor de str.Quedando tu HTML de la siguiente manera:
Hasta el momento este curso va ordenado, la verdad Nicolás explica de una manera que sinceramente se complementa muy bien con la documentación de Angular. :)
creo q hay un pequeño error en cuanto a tipar el array, cuando usamos
names: string[]| number[]=[12,'david'];
no significa q el array puede contener ambos valores si no que el array puede ser de strings o de numbers, es decir no se pueden mezclar por lo q el ejemplo es erróneo.
Para que pueda contener ambos tipos debemos usar any
Concuerdo, pero quiero hacer una pequeña corrección y es que si se quieren usar ambos no tipos lo ideal no es usar any, sino indicar los tipos de la siguiente forma:
names:(string | number)[]=[12,'david']
Usar any es considerado una mala práctica y lo ideal es solo recurrir a este tipo cuando se está migrando de JS a TS y eso que solo como una medida provisional. Si quieren profundizar más pueden ver el curso de Fundamentos de TypeScript
El *ngFor es otra de las estructuras de control en Angular, que nos sirve para iterar un arreglo de elementos o mas conocido como array.
Esta directiva permite renderizar cada elemento dentro de un array, puede ser un array de strings, enteros, fechas, etc. o de elementos mas complejos como un objeto que tiene distintas propiedades, veamos un ejemplo de uso de *ngFor
Primero definimos el arreglo de elementos en el app.component.ts
import{Component}from'@angular/core';@Component({selector:'app-root',templateUrl:'./app.component.html',styleUrls:['./app.component.scss']})exportclassAppComponent{/* Primero definimos en nuestro componte logico el arreagle de elementos */names: string[]=['Nicolas','Julian','Susana','Andrea'];// <-- Arreglo names}
Y despues con el databinding de la propiedad names (nuestro arreglo), lo iteramos con la directiva *ngFor en el app.component.html
<ul><!--Iteramos el arreglo names --><li *ngFor="let item of names; let i = index;"><!-- i es el indice de la posicion del elemento en el array --><label>{{ i }}-{{ item }}</label></li></ul>
Estructura que nos permite iterar un array de elementos. Cadenas, números u objetos.
<h2>ngFor</h2><input type="text" required [(ngModel)]="person.name"/><button(click)="addName(person.name)">Add name</button><ul><li *ngIf="names.length === 0">No hay nombres</li><li *ngFor="let name of names; index as i">{{i}}{{name}}<button(click)="deleteName(i)">Delete</button></li></ul>
<ul><li *ngFor="let name of names; index as i">{{i}}{{ name }}<button(click)="deleteName(i)">Delete</button></li></ul><p *ngIf="names.length === 0">No hay nombres</p>
lo cual significa que si this.newPokemon no contiene data ( está vacío ) no agregue nada, el "&&" es el logical AND y en este caso es usado como short-circuit evaluator, si lo de la izq es verdadero se corre lo de la derecha, en caso contrario no se corre lo de la derecha, por lo que si this.newPokemon si tiene algun valor, si lo agregará es lo mismo que colocar un:
No sé si me estoy adelantando un poco, pero la lista permite cargar elementos vacíos, para que eso no suceda, primero añadí required al input y le agregue un name, luego al botón de carga de elementos lo condicione para que verifique si el input es válido, y dependiendo de si es válido (Renderiza el botón) o no es válido (Desaparece el botón)
Quizas haya una forma mas eficaz pero fue la que se me ocurrio, les comparto mi ejemplo:
<h2>*ngFor</h2><input type="text" required #newNameInput="ngModel"[(ngModel)]="newName"/><button(click)="addNewName()"*ngIf="newNameInput.valid === true">Add name</button><ul><li *ngIf="names.length === 0">No hay nombres</li><li *ngFor="let name of names; index as i">{{ i }}{{" "+ name }}<button(click)="deleteName(i)">Delete</button></li></ul>
<!--Desarrolo del Reto--><h2>MiniSistema de Articulos</h2><h3>RegistrarArticulo</h3><p>Tipo de Inventario del Producto:</p><input type="text"[(ngModel)]="articulo.tipinv"><p>Codigo del Producto:</p><input type="text"[(ngModel)]="articulo.codart"><p>Nombre del Producto:</p><input type="text"[(ngModel)]="articulo.desart"><p>Cantidad del Producto:</p><input type="text"[(ngModel)]="articulo.cantid"><p>Precio del Producto:</p><input type="text"[(ngModel)]="articulo.price"><p>SKU del Producto:</p><input type="text"[(ngModel)]="articulo.sku"><br><button(click)="addArticulo()">Añadir nuevo Articulo</button><h3>Lista de ArticulosRegistrados</h3><table><thead><th>Tipo de Inventario</th><th>Codigo de Articulo</th><th>Descripción de Articulo</th><th>Cantidad</th><th>Price</th><th>SKU</th><th>Eliminar?</th></thead><tbody><tr *ngFor="let fila of articulos; index as i"><td>{{fila.tipinv}}</td><td>{{fila.codart}}</td><td>{{fila.desart}}</td><td>{{fila.cantid}}</td><td>{{fila.price}}</td><td>{{fila.sku}}</td><td><button(click)="deleteArticulo(fila.tipinv, fila.codart)">Eliminar</button></td></tr></tbody></table>
Algo muy interesante seria también lograr que el boton de añadir este activo o desactivo dependiendo de si el input esta vacío o no. Les recomiendo intentarlo para mejorar la lógica de programación.
.
Les comparto mi solución:
.
HTML
.
<h2>ngFor</h2><ul><li *ngFor="let unidad of unidades; index as id">id:{{id}} unidad:{{unidad}}</li></ul><input type="text"(keyup)="checkInput($event)" #inputUnidad="ngModel"[(ngModel)]="nuevaUnidad"><button [disabled]="buttonDisabled"(click)="addUnidad()">Añadir Unidad</button>
.
compontent.ts:
.
buttonDisabled =true;unidades: string[]=['KW01','KW02','KW03'];nuevaUnidad: string ='';addUnidad(){if(this.nuevaUnidad===''){return}else{this.unidades.push(this.nuevaUnidad);}}checkInput(event:Event){const element = event.targetasHTMLInputElement;if(element.value===''){this.buttonDisabled=true;}else{this.buttonDisabled=false;}}
++¡Que vacano!++
En base a lo que hizo Julio, lo modique para que en vez de que desaparezca, aparesca disabled:
<!--Ciclos--><h2>Ciclos</h2><input type="text" required #newNameInput="ngModel"[(ngModel)]="newName"/><button [disabled]="!newNameInput.valid"(click)="addName()">Add name</button><ul><li *ngIf="names.length === 0">No hay nombres disponibles</li><li *ngFor="let name of names; index as i">{{i}}.{{name}}<button(click)="eliminarName(i)">Eliminar</button></li></ul>
Reto ngfor 👌
app.component.ts...
import{Component}from'@angular/core';@Component({selector:'app-root',templateUrl:'./app.component.html',styleUrls:['./app.component.scss']})exportclassAppComponent{ name ='Pia'; age =42; myImg ='https://source.unsplash.com/random'; btnDisabled =true; persons=[{name:'Pia',age:45,avatar:this.myImg,emoji:'😂',phone_number:'3175120737',birthday:'04/06/1980'}] person={name:'Pia',age:45,avatar:this.myImg,emoji:'😂',phone_number:'3175120737',birthday:'04/06/1980'} newPerson={name:'Nombre',age:0,avatar:this.myImg,emoji:'😂',phone_number:'########',birthday:'dd/mes/aa'} newName=""; emojis =['😂','🐦','🐳','🌮','💚'];toggleButton(){this.btnDisabled=!this.btnDisabled;}increaseAge(){this.person.age+=1;}decreaseAge(){this.person.age-=1;}onScroll(event:Event){const element = event.targetasHTMLElement;console.log(element.scrollTop);}changeName(event:Event){const element = event.targetasHTMLInputElement;console.log(element.scrollTop);this.person.name= element.value;}addPerson(){this.persons.push(this.newPerson);this.newPerson={name:'Nombre',age:0,avatar:this.myImg,emoji:'😂',phone_number:'########',birthday:'dd/mes/aa'};}removePerson(i:number){this.persons.splice(i,1);}}
app.component.html...
<h2>Personas(*ngFor Reto)</h2><p>Nombre:<input type="text" required [(ngModel)]="newPerson.name"></p><p>Edad:<input type="text" required [(ngModel)]="newPerson.age"></p><p>Emoji:<input type="text" disabled [(ngModel)]="newPerson.emoji"></p><ul><li *ngFor="let emoji of emojis">{{ emoji }}<button(click)="newPerson.emoji = emoji">Quiero este!</button></li></ul><p>Teléfono:<input type="text" required [(ngModel)]="newPerson.phone_number"></p><p>Nacimiento:<input type="text" required [(ngModel)]="newPerson.birthday"><p><button(click)="addPerson()">Agregar persona</button></p><ul><li *ngIf="persons.length === 0; else elseBlockPerson">No hay mas personas para mostrar</li><ng-template #elseBlockPerson><table><thead><tr><th style="">No.</th><th>Emoji</th><th>Nombre</th><th>Edad</th><th>No.de teléfono</th><th>Cumpleaños</th><th></th></tr></thead><tbody><tr *ngFor="let person of persons; index as i"><td>{{ i+1}}</td><td>{{ person.emoji}}</td><td>{{ person.name}}</td><td>{{ person.age}}</td><td>{{ person.phone_number}}</td><td>{{ person.birthday}}</td><td><button(click)="removePerson(i)">Quitar</button></td></tr></tbody></table></ng-template></ul>