wake-up-neo.com

Iteration mit ngFor loop Map, die den Schlüssel als String und die Werte als Map-Iteration enthält

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>

runtime error

51
Feroz Siddiqui

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>

WORKING DEMO


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>

WORKING DEMO

87
Vivek Doshi

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']]);
}
25
Londeren

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

Stackblitz-Demo

19
David

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.

6
Armen Vardanyan