javascript - Hvordan iterere ved bruk av ngFor-løkke over Map som inneholder nøkkel som streng og verdier som map-iterasjon


Jeg er ny til Angular 5 og prøver å iterere over et kart som inneholder et annet kart i TypeScript. Hvordan iterere over denne typen kart i Angular, nedenfor er kode for komponenten:

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);

  }



}

og dets mal HTML er :

<ul>
  <li *ngFor="let recipient of map.keys()">
    {{recipient}}
   </li>


</ul>

<div>{{map.size}}</div>

Svar #1

For Angular 6.1+, kan du bruke standardpipe keyvalue ( Se også gjennom og gi en stemme ) :

<ul>
    <li *ngFor="let recipient of map | keyvalue">
        {{recipient.key}} --> {{recipient.value}}
    </li>
</ul>

ARBEIDENDE DEMO

For den forrige versjonen :

En enkel løsning på dette er å konvertere kart til array: Array.from

Komponentside :

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());
}

Mal Side :

<ul>
  <li *ngFor="let recipient of getKeys(map)">
    {{recipient}}
   </li>
</ul>

ARBEIDENDE DEMO

Svar #2

Hvis du bruker Angular 6.1 eller senere, er den mest praktiske måten å bruke 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']]);
    }

Svar #3

Rediger

For Angular 6.1 og nyere, bruk KeyValuePipe som foreslått av Londeren.

For angular 6.0 og eldre

For å gjøre ting enklere, kan du lage et rør.

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">

Siden det er rent, vil det ikke bli utløst ved hver endringsdeteksjon, men bare hvis referansen til map-variabelen endres

Stackblitz-demonstrasjon

Svar #4

Dette er fordi map.keys() returnerer en iterator. *ngFor kan fungere med iteratorer, men map.keys() vil bli kalt på hver endringsdeteksjonssyklus, og dermed produsere en ny referanse til arrayet, noe som resulterer i feilen du ser. Forresten, dette er ikke alltid en feil slik du tradisjonelt ville tenke på det; det kan til og med ikke bryte noen av funksjonene dine, men antyder at du har en datamodell som ser ut til å oppføre seg på en sprø måte - endres raskere enn endringsdetektoren sjekker verdien.

Hvis du ikke vil konvertere kartet til en array i komponenten din, kan du bruke pipen som er foreslått i kommentarene. Det ser ikke ut til å finnes noen annen løsning.

P.S. Denne feilen vil ikke vises i produksjonsmodus, da det mer er som en veldig streng advarsel, snarere enn en faktisk feil, men likevel, det er ikke en god idé å la det være.

Relaterte artikler