在Angular中迭代对象

我正在尝试在Angular 2 Alpha 28中做一些事情,并在字典和NgFor中遇到问题。

我在TypeScript中有一个接口,看起来像这样:

interface Dictionary { [ index: string ]: string } 

在JavaScript中,这将转化为一个对象,其中的数据可能看起来像这样:

 myDict={'key1':'value1','key2':'value2'} 

我想迭代这个,并试着这个:

 <div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div> 

但无济于事,下面也没有一个工作:

 <div *ngFor="#value of myDict">{{value}}</div> <div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div> 

在所有情况下,我得到像“意外的标记”或“无法find”iterableDiff“pipe道支持对象”

我在这里错过了什么? 这不可能了吗? (第一种语法在Angular 1.x中有效)或者迭代对象的语法是不同的?

看来他们不想支持ng1的语法。

根据MiškoHevery( 参考 ):

地图没有按键的顺序,因此迭代是不可预知的。 这在ng1中得到了支持,但我们认为这是一个错误,在NG2中不会得到支持

计划是有一个mapToIterablepipe道

<div *ngFor"var item of map | mapToIterable">

所以为了迭代你的对象,你将需要使用“pipe道”。 目前没有这样做的pipe道 。

作为一种解决方法,下面是一个迭代键的小例子:

零件:

 import {Component} from 'angular2/core'; @Component({ selector: 'component', templateUrl: ` <ul> <li *ngFor="#key of keys();">{{key}}:{{myDict[key]}}</li> </ul> ` }) export class Home { myDict : Dictionary; constructor() { this.myDict = {'key1':'value1','key2':'value2'}; } keys() : Array<string> { return Object.keys(this.myDict); } } interface Dictionary { [ index: string ]: string } 

尝试使用这个pipe道

 @Pipe({ name: 'values', pure: false }) export class ValuesPipe implements PipeTransform { transform(value: any, args: any[] = null): any { return Object.keys(value).map(key => value[key]); } } <div *ngFor="#value of object | values"> </div> 

正如其他答案所提到的那样,它在ng2中不被支持,所以这里有一个解决方法:使用键值对

pipe道:

 @Pipe({ name: 'mapToIterable' }) export class MapToIterable { transform(dict: Object): Array { var a = []; for (var key in dict) { if (dict.hasOwnProperty(key)) { a.push({key: key, val: dict[key]}); } } return a; } } 

用法:

 <div *ngFor="#keyValuePair of someObject | mapToIterable"> This is the key {{keyValuePair.key}} and this is the value {{keyValuePair.val}}. </div> 

除了@ obscur的答案,这里是一个如何从@View中访问keyvalue的例子。

pipe:

 @Pipe({ name: 'keyValueFilter' }) export class keyValueFilterPipe { transform(value: any, args: any[] = null): any { return Object.keys(value).map(function(key) { let pair = {}; let k = 'key'; let v = 'value' pair[k] = key; pair[v] = value[key]; return pair; }); } } 

视图:

 <li *ngFor="#u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li> 

所以如果对象看起来像:

 myObject = { Daario: Naharis, Victarion: Greyjoy, Quentyn: Ball } 

生成的结果将是:

名字:Daario
姓氏:Naharis

名字:Victarion
姓氏:Greyjoy

名字:昆汀
姓氏:球

增加SimonHawesome的优秀答案 。 我做了一个简洁的版本,它利用了一些新的打字稿function。 我意识到,SimonHawesome的版本是故意详细解释的基本细节。 我还添加了一个早期检查,以便pipe道为虚假值工作。 例如,如果地图是null

请注意,使用迭代器转换(如此处所做的)可以更高效,因为我们不需要为临时数组分配内存(如其他答案中所做的那样)。

 import {Pipe, PipeTransform} from '@angular/core'; @Pipe({ name: 'mapToIterable' }) export class MapToIterable implements PipeTransform { transform(map: { [key: string]: any }, ...parameters: any[]) { if (!map) return undefined; return Object.keys(map) .map((key) => ({ 'key': key, 'value': map[key] })); } } 

以下是一些支持多种转换(keyval,key,value)的答案的变体:

 import { Pipe, PipeTransform } from '@angular/core'; type Args = 'keyval'|'key'|'value'; @Pipe({ name: 'mapToIterable', pure: false }) export class MapToIterablePipe implements PipeTransform { transform(obj: {}, arg: Args = 'keyval') { return arg === 'keyval' ? Object.keys(obj).map(key => ({key: key, value: obj[key]})) : arg === 'key' ? Object.keys(obj) : arg === 'value' ? Object.keys(obj).map(key => obj[key]) : null; } } 

用法

 map = { 'a': 'aee', 'b': 'bee', 'c': 'see' } <div *ngFor="let o of map | mapToIterable">{{o.key}}: {{o.value}}</div> <div>a: aee</div> <div>b: bee</div> <div>c: see</div> <div *ngFor="let o of map | mapToIterable:'keyval'">{{o.key}}: {{o.value}}</div> <div>a: aee</div> <div>b: bee</div> <div>c: see</div> <div *ngFor="let k of map | mapToIterable:'key'">{{k}}</div> <div>a</div> <div>b</div> <div>c</div> <div *ngFor="let v of map | mapToIterable:'value'">{{v}}</div> <div>aee</div> <div>bee</div> <div>see</div> 

我有一个类似的问题,为对象和地图build立了一些东西。

 import { Pipe } from 'angular2/core.js'; /** * Map to Iteratble Pipe * * It accepts Objects and [Maps](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) * * Example: * * <div *ngFor="#keyValuePair of someObject | mapToIterable"> * key {{keyValuePair.key}} and value {{keyValuePair.value}} * </div> * */ @Pipe({ name: 'mapToIterable' }) export class MapToIterable { transform(value) { let result = []; if(value.entries) { for (var [key, value] of value.entries()) { result.push({ key, value }); } } else { for(let key in value) { result.push({ key, value: value[key] }); } } return result; } } 

如果有人想知道如何使用多维对象,这是解决scheme。

让我们假设我们在服务中有下面的对象

 getChallenges() { var objects = {}; objects['0'] = { title: 'Angular2', description : "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." }; objects['1'] = { title: 'AngularJS', description : "Lorem Ipsum is simply dummy text of the printing and typesetting industry." }; objects['2'] = { title: 'Bootstrap', description : "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", }; return objects; } 

在组件中添加以下function

 challenges; constructor(testService : TestService){ this.challenges = testService.getChallenges(); } keys() : Array<string> { return Object.keys(this.challenges); } 

最后鉴于下面

 <div *ngFor="#key of keys();"> <h4 class="heading">{{challenges[key].title}}</h4> <p class="description">{{challenges[key].description}}</p> </div> 

Angular 2.x && Angular 4.x不支持这个框

您可以使用这两个pipe道按键或按迭代。

钥匙pipe道:

 import {Pipe, PipeTransform} from '@angular/core' @Pipe({ name: 'keys', pure: false }) export class KeysPipe implements PipeTransform { transform(value: any, args: any[] = null): any { return Object.keys(value) } } 

值pipe道:

 import {Pipe, PipeTransform} from '@angular/core' @Pipe({ name: 'values', pure: false }) export class ValuesPipe implements PipeTransform { transform(value: any, args: any[] = null): any { return Object.keys(value).map(key => value[key]) } } 

如何使用:

 let data = {key1: 'value1', key2: 'value2'} <div *ngFor="let key of data | keys"></div> <div *ngFor="let value of data | values"></div> 

在JavaScript中,这将转化为一个对象,其中的数据可能看起来像这样

TypeScript中的接口是一个开发时间构造(纯粹用于工具… 0运行时影响)。 你应该写和JavaScript一样的TypeScript。

字典是一个对象,而不是一个数组。 我相信ng-repeat需要Angular 2中的一个数组。

最简单的解决scheme是创build一个pipe道/filter,将对象转换为数组。 也就是说,你可能想要使用@basarat所说的数组。

如果你有es6-shim或你的tsconfig.json目标es6 ,你可以使用ES6 Map来创build它。

 var myDict = new Map(); myDict.set('key1','value1'); myDict.set('key2','value2'); <div *ngFor="let keyVal of myDict.entries()"> key:{{keyVal[0]}}, val:{{keyVal[1]}} </div>