source

키를 문자열로, 값을 맵 반복으로 포함하는 ngFor 루프 맵을 사용하여 반복하는 방법

itover 2023. 3. 13. 20:24
반응형

키를 문자열로, 값을 맵 반복으로 포함하는 ngFor 루프 맵을 사용하여 반복하는 방법

나는 angular 5에 처음 와서 타이프 스크립트에 다른 지도가 포함된 지도를 반복하려고 한다.이러한 종류의 맵 아래에서 아래 각도로 반복하는 방법은 컴포넌트의 코드입니다.

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

  }



}

템플릿 html은 다음과 같습니다.

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


</ul>

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

런타임 오류

Angular 6.1+의 경우 기본 파이프(Do review and upvote도 참조)를 사용할 수 있습니다.

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

작업 데모


이전 버전의 경우:

이를 위한 간단한 솔루션 중 하나는 맵을 Array.from으로 변환하는 것입니다.

컴포넌트측:

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

템플릿 측:

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

작업 데모

Angular 6.1 이후를 사용하는 경우 가장 편리한 방법은 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']]);
    }

편집

각도 6.1 이후의 경우 Londeren에서 제안한 대로 KeyValuePipe를 사용합니다.

각도 6.0 이상일 경우

쉽게 하기 위해 파이프를 작성할 수 있습니다.

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

순수하기 때문에 모든 변경 검출에서 트리거되는 것은 아니지만, 에 대한 참조가map가변 변화

Stackblitz 데모

그 이유는map.keys()반복기를 반환합니다. *ngFor반복기를 사용할 수 있지만map.keys()는, 변경 검출 사이클 마다 호출되기 때문에, 어레이에 대한 새로운 참조가 생성되어 에러가 표시됩니다.덧붙여서, 이것은, 종래의 생각대로의 에러라고는 할 수 없습니다.또한, 기능을 망가뜨리는 일은 없을지도 모릅니다.다만, 변경 검출기가 그 값을 체크하는 것보다 빠르게 변화하고 있는 것처럼 보이는 데이터 모델을 사용하고 있는 것을 알 수 있습니다.

맵을 컴포넌트의 배열로 변환하지 않을 경우 코멘트에 제시된 파이프를 사용할 수 있습니다.다른 회피책은 없는 것 같습니다.

추신: 이 오류는 실제 오류라기보다는 매우 엄격한 경고에 가깝기 때문에 프로덕션 모드에서는 표시되지 않지만 그대로 두는 것은 좋지 않습니다.

각도keyvalue파이프는 사용할 수 있지만 유감스럽게도 키에 따라 정렬됩니다.지도는 이미 주문이 있고, 그것을 유지할 수 있으면 좋을 것 같아요!

자체 파이프를 정의할 수 있습니다.mapkeyvalue맵의 항목 순서를 유지합니다.

import { Pipe, PipeTransform } from '@angular/core';

// Holds a weak reference to its key (here a map), so if it is no longer referenced its value can be garbage collected.
const cache = new WeakMap<ReadonlyMap<any, any>, Array<{ key: any; value: any }>>();

@Pipe({ name: 'mapkeyvalue', pure: true })
export class MapKeyValuePipe implements PipeTransform {
  transform<K, V>(input: ReadonlyMap<K, V>): Iterable<{ key: K; value: V }> {
    const existing = cache.get(input);
    if (existing !== undefined) {
      return existing;
    }

    const iterable = Array.from(input, ([key, value]) => ({ key, value }));
    cache.set(input, iterable);
    return iterable;
  }
}

다음과 같이 사용할 수 있습니다.

<mat-select>
  <mat-option *ngFor="let choice of choicesMap | mapkeyvalue" [value]="choice.key">
    {{ choice.value }}
  </mat-option>
</mat-select>

사람들이 코멘트에서 언급한 바와 같이 키 값 파이프는 삽입 순서를 유지하지 않습니다(Map의 주요 목적).

어쨌든 Map 객체가 있고 순서를 유지하는 가장 깨끗한 방법은 entries() 함수인 것 같습니다.

<ul>
    <li *ngFor="let item of map.entries()">
        <span>key: {{item[0]}}</span>
        <span>value: {{item[1]}}</span>
    </li>
</ul>

언급URL : https://stackoverflow.com/questions/48187362/how-to-iterate-using-ngfor-loop-map-containing-key-as-string-and-values-as-map-i

반응형