Soy nuevo en angular 5 y trato de iterar el mapa que contiene otro mapa en mecanografiado. Cómo iterar debajo de este tipo de mapa en angular a continuación es el código para el componente:
import { Component, OnInit} from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
map = new Map<String, Map<String,String>>();
map1 = new Map<String, String>();
constructor() {
}
ngOnInit() {
this.map1.set("sss","sss");
this.map1.set("aaa","sss");
this.map1.set("sass","sss");
this.map1.set("xxx","sss");
this.map1.set("ss","sss");
this.map1.forEach((value: string, key: string) => {
console.log(key, value);
});
this.map.set("yoyoy",this.map1);
}
}
y su plantilla html es:
<ul>
<li *ngFor="let recipient of map.keys()">
{{recipient}}
</li>
</ul>
<div>{{map.size}}</div>
javascript
angular
typescript
angular-cli
Feroz Siddiqui
fuente
fuente
Respuestas:
Para Angular 6.1+ , puede usar la tubería predeterminada
keyvalue
(también revisar y votar ):<ul> <li *ngFor="let recipient of map | keyvalue"> {{recipient.key}} --> {{recipient.value}} </li> </ul>
DEMO DE TRABAJO
Para la versión anterior:
Una solución simple a esto es convertir mapa en matriz: Array.from
Lado del componente:
map = new Map<String, String>(); constructor(){ this.map.set("sss","sss"); this.map.set("aaa","sss"); this.map.set("sass","sss"); this.map.set("xxx","sss"); this.map.set("ss","sss"); this.map.forEach((value: string, key: string) => { console.log(key, value); }); } getKeys(map){ return Array.from(map.keys()); }
Lado de la plantilla:
<ul> <li *ngFor="let recipient of getKeys(map)"> {{recipient}} </li> </ul>
DEMO DE TRABAJO
fuente
map
disponible, puede usar ese para usar todos los beneficios del Mapawhy he needed this kind of requirement
, él puede explicarte mejor :)Si está usando Angular 6.1 o posterior, la forma más conveniente es usar KeyValuePipe
@Component({ selector: 'keyvalue-pipe', template: `<span> <p>Object</p> <div *ngFor="let item of object | keyvalue"> {{item.key}}:{{item.value}} </div> <p>Map</p> <div *ngFor="let item of map | keyvalue"> {{item.key}}:{{item.value}} </div> </span>` }) export class KeyValuePipeComponent { object: Record<number, string> = {2: 'foo', 1: 'bar'}; map = new Map([[2, 'foo'], [1, 'bar']]); }
fuente
map
tipo que se encarga de usarla con*ngFor
Editar
Para angular 6.1 y posteriores, use KeyValuePipe como lo sugiere Londeren.
Para angular 6.0 y anteriores
Para facilitar las cosas, puede crear una tubería.
import {Pipe, PipeTransform} from '@angular/core'; @Pipe({name: 'getValues'}) export class GetValuesPipe implements PipeTransform { transform(map: Map<any, any>): any[] { let ret = []; map.forEach((val, key) => { ret.push({ key: key, val: val }); }); return ret; } } <li *ngFor="let recipient of map |getValues">
Como es puro, no se activará en cada detección de cambio, sino solo si
map
cambia la referencia a la variableDemostración de Stackblitz
fuente
Esto se debe a que
map.keys()
devuelve un iterador.*ngFor
puede funcionar con iteradores, peromap.keys()
se llamará en cada ciclo de detección de cambios, lo que producirá una nueva referencia a la matriz, lo que dará como resultado el error que ve. Por cierto, esto no siempre es un error como lo pensaría tradicionalmente; incluso puede que no rompa ninguna de sus funciones, pero sugiere que tiene un modelo de datos que parece comportarse de una manera loca, cambiando más rápido de lo que el detector de cambios verifica su valor.Si no desea convertir el mapa en una matriz en su componente, puede usar la tubería sugerida en los comentarios. No hay otra solución, como parece.
PD: Este error no se mostrará en el modo de producción, ya que es más como una advertencia muy estricta, en lugar de un error real, pero aún así, no es una buena idea dejarlo así.
fuente
Como la gente ha mencionado en los comentarios, la tubería keyvalue no conserva el orden de inserción (que es el propósito principal de Map).
De todos modos, parece que si tiene un objeto Mapa y desea conservar el orden, la forma más limpia de hacerlo es la función Entradas ():
<ul> <li *ngFor="let item of map.entries()"> <span>key: {{item[0]}}</span> <span>value: {{item[1]}}</span> </li> </ul>
fuente
El siguiente código es útil para mostrar en el orden de inserción del mapa .
<ul> <li *ngFor="let recipient of map | keyvalue: asIsOrder"> {{recipient.key}} --> {{recipient.value}} </li> </ul>
Archivo .ts agregue el siguiente código.
asIsOrder(a, b) { return 1; }
fuente