对于如何在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中有任何内建的管道来做同样的事情吗?
像这样创建数组
tags = [
{
name : 'Aliko Dogara',
amount : '60,000',
purpose: 'Office repairs'
},
{
name : 'Aliko Dogara',
amount : '60,000',
purpose: 'Office repairs'
},
{
name : 'Aliko Dogara',
amount : '60,000',
purpose: 'Office repairs'
},
{
name : 'Aliko Dogara',
amount : '60,000',
purpose: 'Office repairs'
},
{
name : 'Aliko Dogara',
amount : '60,000',
purpose: 'Office repairs'
}
];
一直都有效
在Angular 6.1中,你可以使用keyvalue管道:
<div *ngFor="let item of testObject | keyvalue">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</div>
但是它有一个不方便的地方,就是根据键值对结果列表进行排序。
如果你需要中性的东西:
@Pipe({ name: 'keyValueUnsorted', pure: false })
export class KeyValuePipe implements PipeTransform {
transform(input: any): any {
let keys = [];
for (let key in input) {
if (input.hasOwnProperty(key)) {
keys.push({ key: key, value: input[key]});
}
}
return keys;
}
}
不要忘记指定pure:false管道属性。在这种情况下,管道在每个更改检测周期中都被调用,即使输入引用没有更改(向对象添加属性时也是如此)。
@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);
}
}
}
您可以创建一个自定义管道来返回每个元素的键列表。
就像这样:
import { PipeTransform, Pipe } from '@angular/core';
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push(key);
}
return keys;
}
}
像这样使用它:
<tr *ngFor="let c of content">
<td *ngFor="let key of c | keys">{{key}}: {{c[key]}}</td>
</tr>
Edit
你也可以返回一个包含键和值的条目:
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
transform(value, args:string[]) : any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}
像这样使用它:
<span *ngFor="let entry of content | keys">
Key: {{entry.key}}, value: {{entry.value}}
</span>