对于如何在angular2中使用*ngFor迭代对象时获取对象的键和值,我有点困惑。我知道角1。X有一个语法

ng-repeat="(key, value) in demo"

但是我不知道如何在angular2中做同样的事情。我也做过类似的尝试,但没有成功:

    <ul>
      <li *ngFor='#key of demo'>{{key}}</li>
    </ul>

    demo = {
        'key1': [{'key11':'value11'}, {'key12':'value12'}],
        'key2': [{'key21':'value21'}, {'key22':'value22'}],
      }

以下是我的尝试: http://plnkr.co/edit/mIj619FncOpfdwrR0KeG?p=preview

如何使用*ngFor动态获取key1和key2 ?经过广泛的搜索,我发现了使用管道的想法,但我不知道如何去做。 在angar2中有任何内建的管道来做同样的事情吗?


当前回答

这里有一个简单的解决方案

你可以为此使用typescript迭代器

import {Component} from 'angular2/core';
declare var Symbol;
@Component({
    selector: 'my-app',
    template:`<div>
    <h4>Iterating an Object using Typescript Symbol</h4><br>
Object is : <p>{{obj | json}}</p>
</div>
============================<br>
Iterated object params are:
<div *ngFor="#o of obj">
{{o}}
</div>

`
})
export class AppComponent {
  public obj: any = {
    "type1": ["A1", "A2", "A3","A4"],
    "type2": ["B1"],
    "type3": ["C1"],
    "type4": ["D1","D2"]
  };

  constructor() {
    this.obj[Symbol.iterator] =  () => {
          let i =0;

          return {
            next: () => {
              i++;
              return {
                  done: i > 4?true:false,
                  value: this.obj['type'+i]
              }
            }
          }
    };
  }
}

http://plnkr.co/edit/GpmX8g?p=info

其他回答

有对象。在*ngFor中使用它。

@Component({
  selector: 'app-myview',
  template: `<div *ngFor="let key of objectKeys(items)">{{key + ' : ' + items[key]}}</div>`
})

export class MyComponent {
  objectKeys = Object.keys;
  items = { keyOne: 'value 1', keyTwo: 'value 2', keyThree: 'value 3' };
  constructor(){}
}

@Marton对接受的答案有一个重要的反对意见,理由是管道在每次更改检测时都会创建一个新的集合。相反,我将创建一个HtmlService,它提供了一系列实用函数,视图可以使用如下:

@Component({
  selector: 'app-myview',
  template: `<div *ngFor="let i of html.keys(items)">{{i + ' : ' + items[i]}}</div>`
})
export class MyComponent {
  items = {keyOne: 'value 1', keyTwo: 'value 2', keyThree: 'value 3'};
  constructor(private html: HtmlService){}
}

@Injectable()
export class HtmlService {
  keys(object: {}) {
    return Object.keys(object);
  }
  // ... other useful methods not available inside html, like isObject(), isArray(), findInArray(), and others...
}

更新

在6.1.0-beta.1KeyValuePipe是https://github.com/angular/angular/pull/24319引入的

<div *ngFor="let item of {'b': 1, 'a': 1} | keyvalue">
  {{ item.key }} - {{ item.value }}
</div>

砰砰作响的例子

之前的版本

另一种方法是创建NgForIn指令,如下所示:

<div *ngFor="let key in obj">
   <b>{{ key }}</b>: {{ obj[key] }}
</div>

砰砰作响的例子

ngforin.directive.ts

@Directive({
  selector: '[ngFor][ngForIn]'
})
export class NgForIn<T> extends NgForOf<T> implements OnChanges {

  @Input() ngForIn: any;

  ngOnChanges(changes: NgForInChanges): void {
    if (changes.ngForIn) {
      this.ngForOf = Object.keys(this.ngForIn) as Array<any>;

      const change = changes.ngForIn;
      const currentValue = Object.keys(change.currentValue);
      const previousValue = change.previousValue ? Object.keys(change.previousValue) : undefined;
      changes.ngForOf =  new SimpleChange(previousValue, currentValue, change.firstChange);

      super.ngOnChanges(changes);
    }
  }
}

我认为是客体。钥匙是这个问题的最佳解决方案。对于任何遇到这个答案并试图找出为什么Object的人。Keys给他们['0','1']而不是['key1', 'key2'],这是一个警示性的故事-注意“of”和“in”之间的区别:

我已经在使用Object了。键,类似于这个:

interface demo {
    key: string;
    value: string;
}

createDemo(mydemo: any): Array<demo> {
    const tempdemo: Array<demo> = [];

    // Caution: use "of" and not "in"
    for (const key of Object.keys(mydemo)) {
        tempdemo.push(
            { key: key, value: mydemo[key]}
        );
    }

    return tempdemo;
}

然而,与其

for (const key OF Object.keys(mydemo)) {

我无意中写了

for (const key IN Object.keys(mydemo)) {

哪个“工作”完全正常,没有任何错误并返回

[{key: '0', value: undefined}, {key: '1', value: undefined}]

这花了我2个小时在谷歌上搜索和咒骂。

(打了额头上)

在其他优秀的管道中,有一个非常好的库可以做到这一点。它叫做ngx管道。

例如,keys管道返回对象的键,values管道返回对象的值:

钥匙管

<div *ngFor="let key of {foo: 1, bar: 2} | keys">{{key}}</div> 
<!-- Output: 'foo' and 'bar -->

价值管

<div *ngFor="let value of {foo: 1, bar: 2} | values">{{value}}</div>
<!-- Output: 1 and 2 -->

不需要创建自己的自定义管道:)