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


109

저는 앵귤러 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>

런타임 에러



내가 배열에 내지도를 변환 싶어 그나마 해결책은 무엇인가
Feroz 시디키


덕분에 아주 잘 작동
Feroz 시디키

답변:


246

Angular 6.1+의 경우 기본 파이프를 사용할 수 있습니다 keyvalue( Do review and upvote also ) :

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

작업 데모


1
if map = new Map <String, Map <String, String >> (); 어떻게 작동합니까?
Feroz Siddiqui

@FerozSiddiqui, 답변을 업데이트했으며 모든 중첩 수준에서 작동한다고 생각합니다.
Vivek Doshi

마지막으로 배열로 변환하면 모든 맵 기능이 손실됩니다. 그렇다면 Map의 이점은 무엇입니까?
diEcho

1
@ pro.mean, 우리는 반복 할 일부 반복을 원하기 때문에 각도 템플릿을 통해 반복하기를 원하기 때문에 변환하고 있습니다. 그리고 당신은 여전히 원래의 목적이 map가능합니다 하나는지도의 모든 혜택을 사용할 수 있음을 사용할 수 있습니다
비벡 트레이 도시

1
@ pro.mean, 템플릿 측에 표시하기 위해 변환했지만 여전히 구성 요소 측에서 사용할 수있는 Map obaject가 있습니다. 당신은 영업 이익에 요청할 수 있습니다 why he needed this kind of requirement, 그는 :) 더 나은 서비스를 설명 할 수
비벡 트레이 도시

48

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

3
사람들이 스크롤하여이 답변을 볼 수 있기를 바랍니다. 왜냐하면 제가 사용하는 내 map유형에 사용할 수있는이 기본 파이프를 볼 때까지 리팩터링을 수행하려고했기 때문 입니다*ngFor
atconway

2
당신이 수정에 그 비교 자 기능을 추가 할 필요가 :-(지도의 초기 정렬을 키 값 유지하지 않는 것 같습니다
콘스탄틴 Vahrushev

1
사실입니다. 그리고 여기에 문제가 있습니다. github.com/angular/angular/issues/31420
Londeren

24

편집하다

각도 6.1 이상에서는 Londeren에서 제안한대로 KeyValuePipe 를 사용하십시오 .

Angular 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 데모


파이프가 변경 사항을 확인하고 "순수"가 아니기 때문에 모든 변경 감지주기에서 전체 반복을 수행 할 것이라고 생각합니다. 반대표를 던지지 않았지만 그게 이유일까요?
Drenai

5
@Ryan Pipes는 기본적으로 순수합니다. 파이프에 console.log를 추가하면 여러 번 호출되지 않는다는 것을 알 수 있습니다. 하지만 수용된 솔루션의 구성 요소 방법은 ...
David

1
나는 그것을 거꾸로 얻었다!
알려

10

이는 map.keys()반복자를 반환 하기 때문 입니다. *ngFor반복자와 함께 작동 할 수 있지만는 map.keys()모든 변경 감지주기에서 호출되므로 배열에 대한 새 참조가 생성되어 오류가 발생합니다. 그건 그렇고, 이것은 당신이 전통적으로 생각하는 것처럼 항상 오류 가 아닙니다 . 기능을 손상시키지 않을 수도 있지만 미친 방식으로 작동하는 것처럼 보이는 데이터 모델이 있음을 시사합니다. 변경 감지기가 값을 확인하는 것보다 빠르게 변경됩니다.

구성 요소에서 맵을 배열로 변환하지 않으려면 주석에 제안 된 파이프를 사용할 수 있습니다. 보이는 것처럼 다른 해결 방법은 없습니다.

PS이 오류는 실제 오류가 아닌 매우 엄격한 경고와 비슷하기 때문에 프로덕션 모드에서는 표시되지 않지만 여전히 그대로 두는 것은 좋지 않습니다.


1

사람들이 주석에서 언급했듯이 키 값 파이프는 삽입 순서를 유지하지 않습니다 (Map의 주요 목적).

어쨌든 Map 객체가 있고 순서를 유지하려는 경우 가장 깔끔한 방법은 items () 함수입니다.

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

github.com/angular/angular/issues/31420#issuecomment-635377113을 참조하십시오. .entries () 사용을 피해야하는 이유
Florian

1

아래 코드는 지도 게재 신청서 에 표시하는 데 유용합니다 .

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

.ts 파일 은 아래 코드를 추가합니다.

asIsOrder(a, b) {
    return 1;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.