Ich bin neu in angular 5 und versuche, die Map mit einer anderen Map in TypeScript zu iterieren. Wie unter dieser Art von Karte in angular iteriert wird, ist Code für Komponente:
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);
}
}
und seine Vorlage HTML ist:
<ul>
<li *ngFor="let recipient of map.keys()">
{{recipient}}
</li>
</ul>
<div>{{map.size}}</div>
Für Angular 6.1 + können Sie die Standardpipe keyvalue
( Bitte auch überprüfen ):
<ul>
<li *ngFor="let recipient of map | keyvalue">
{{recipient.key}} --> {{recipient.value}}
</li>
</ul>
Für die vorherige Version:
Eine einfache Lösung hierfür ist die Konvertierung der Karte in ein Array: Array.from
Komponentenseite:
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());
}
Vorlagenseite:
<ul>
<li *ngFor="let recipient of getKeys(map)">
{{recipient}}
</li>
</ul>
Wenn Sie Angular 6.1 oder höher verwenden, ist die bequemste Methode 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']]);
}
Bearbeiten
Verwenden Sie für angular 6.1 und höher) die von Londeren vorgeschlagene KeyValuePipe .
Für angular 6.0 und älter
Zur Vereinfachung können Sie eine Pipe erstellen.
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">
Da es rein ist, wird es nicht bei jeder Änderungserkennung ausgelöst, sondern nur, wenn sich der Verweis auf die Variable map
ändert
Dies liegt daran, dass map.keys()
einen Iterator zurückgibt. *ngFor
Kann mit Iteratoren arbeiten, aber die Funktion map.keys()
wird bei jedem Änderungserkennungszyklus aufgerufen, wodurch ein neuer Verweis auf das Array erstellt wird, was zu dem angezeigten Fehler führt. Übrigens ist dies nicht immer ein Fehler, wie Sie es traditionell denken würden; Es kann sogar sein, dass Ihre Funktionalität nicht beeinträchtigt wird. Es deutet jedoch darauf hin, dass Sie ein Datenmodell haben, das sich verrückt zu verhalten scheint. Es ändert sich schneller, als der Änderungsdetektor seinen Wert überprüft.
Wenn Sie die Map nicht in ein Array in Ihrer Komponente konvertieren möchten, können Sie die in den Kommentaren vorgeschlagene Pipe verwenden. Wie es scheint, gibt es keine andere Problemumgehung.
P.S. Dieser Fehler wird im Produktionsmodus nicht angezeigt, da es sich eher um eine sehr strenge Warnung als um einen tatsächlichen Fehler handelt. Es ist jedoch keine gute Idee, diesen Fehler zu belassen.