私はangular 5が初めてで、TypeScriptで別のマップを含むマップを反復しようとしています。コンポーネントのコードは、以下のangularのこの種類のマップの下で反復する方法です。
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 +の場合、デフォルトのパイプkeyvalue
を使用できます=( レビューも行う ):
<ul>
<li *ngFor="let recipient of map | keyvalue">
{{recipient.key}} --> {{recipient.value}}
</li>
</ul>
以前のバージョンの場合:
これに対する単純な解決策の1つは、マップを配列に変換することです: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']]);
}
編集
angular 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
変数への参照が変更された場合にのみトリガーされます
これは、map.keys()
がイテレータを返すためです。 *ngFor
はイテレータで動作しますが、map.keys()
は変更検出サイクルごとに呼び出されるため、配列への新しい参照が生成され、表示されるエラーが発生します。ところで、これはあなたが伝統的に考えているように、常にerrorであるとは限りません。機能を壊すことはないかもしれませんが、異常な方法で動作しているように見えるデータモデルがあることを示唆しています。変更検出器が値をチェックするよりも速く変化します。
コンポーネント内でマップを配列に変換したくない場合は、コメントで提案されているパイプを使用できます。考えられるように、他の回避策はありません。
追伸このエラーは、実際のエラーではなく、非常に厳密な警告に近いため、本番モードでは表示されませんが、そのままにしておくことはお勧めできません。