Я новичок в angular 5 и пытаюсь перебрать карту, содержащую другую карту, в машинописном тексте. Как выполнить итерацию ниже этого вида карты в 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>
javascript
angular
typescript
angular-cli
Фероз Сиддики
источник
источник
Ответы:
Для Angular 6.1+ вы можете использовать канал по умолчанию
keyvalue
(также просмотрите и проголосуйте ):<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>
РАБОЧАЯ ДЕМО
источник
map
доступный оригинальный объект, вы можете использовать его, чтобы использовать все преимущества Картыwhy he needed this kind of requirement
, он вам лучше объяснит :)Если вы используете 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']]); }
источник
map
типа , который заботится о его использовании с*ngFor
редактировать
Для angular 6.1 и новее используйте KeyValuePipe, как предлагает Londeren.
Для 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
источник
Это потому, что
map.keys()
возвращает итератор.*ngFor
может работать с итераторами, ноmap.keys()
будет вызываться в каждом цикле обнаружения изменений, создавая новую ссылку на массив, что приведет к ошибке, которую вы видите. Кстати, это не всегда ошибка, как вы традиционно думаете; он может даже не нарушить вашу функциональность, но предполагает, что у вас есть модель данных, которая, кажется, ведет себя безумно - изменяется быстрее, чем детектор изменений проверяет свое значение.Если вы не хотите преобразовывать карту в массив в вашем компоненте, вы можете использовать конвейер, предложенный в комментариях. Похоже, другого обходного пути нет.
PS Эта ошибка не будет отображаться в производственном режиме, поскольку она больше похожа на очень строгое предупреждение, чем на фактическую ошибку, но, тем не менее, оставлять ее - не лучшая идея.
источник
Как люди упоминали в комментариях, канал ключевого значения не сохраняет порядок вставки (что является основной целью карты).
Во всяком случае, похоже, что если у вас есть объект Map и вы хотите сохранить порядок, самый чистый способ сделать это - это функция entry ():
<ul> <li *ngFor="let item of map.entries()"> <span>key: {{item[0]}}</span> <span>value: {{item[1]}}</span> </li> </ul>
источник
The below code useful to display in the map insertion order.
<ul> <li *ngFor="let recipient of map | keyvalue: asIsOrder"> {{recipient.key}} --> {{recipient.value}} </li> </ul>
.ts file add the below code.
asIsOrder(a, b) { return 1; }
источник