access key and value of object using *ngFor

2018-12-31 05:11发布

Bit confused about how to get Key and Value of an object in angular2 while using *ngFor for iteration over the object. I know in angular 1.x there is syntax like

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

but in angular2 I don't know I tried the same but didn't get successful. I have tried the below code but didn't run please tell me where I am doing wrong.

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

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

here is plnkr where I have tried the same : http://plnkr.co/edit/mIj619FncOpfdwrR0KeG?p=preview

I want to get key1 and key2 dynamically using *ngFor. How to get it? I searched a lot found the idea of using pipe but how to use I don't know. is there any inbuild pipe for doing same in angular2?

15条回答
刘海飞了
2楼-- · 2018-12-31 05:34

If you're already using Lodash, you can do this simple approach which includes both key and value:

<ul>
  <li *ngFor='let key of _.keys(demo)'>{{key}}: {{demo[key]}}</li>
</ul>

In the typescript file, include:

import * as _ from 'lodash';

and in the exported component, include:

_: any = _;
查看更多
何处买醉
3楼-- · 2018-12-31 05:34

Thanks for the pipe but i had to make some changes before i could use it in angular 2 RC5. Changed the Pipe import line and also added type of any to the keys array initialization.

 import {Pipe, PipeTransform} from '@angular/core';

 @Pipe({name: 'keys'})
 export class KeysPipe implements PipeTransform {
 transform(value) {
   let keys:any = [];
   for (let key in value) {
      keys.push( {key: key, value: value[key]} );
    }
     return keys;
  }
}
查看更多
十年一品温如言
4楼-- · 2018-12-31 05:37

You could create a custom pipe to return the list of key for each element. Something like that:

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;
  }
}

and use it like that:

<tr *ngFor="let c of content">           
  <td *ngFor="let key of c | keys">{{key}}: {{c[key]}}</td>
</tr>

Edit

You could also return an entry containing both key and value:

@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;
  }
}

and use it like that:

<span *ngFor="let entry of content | keys">           
  Key: {{entry.key}}, value: {{entry.value}}
</span>
查看更多
千与千寻千般痛.
5楼-- · 2018-12-31 05:37

There's a real nice library that does this among other nice pipes. It's called ngx-pipes.

For example, keys pipe returns keys for an object, and values pipe returns values for an object:

keys pipe

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

values pipe

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

No need to create your own custom pipe :)

查看更多
冷夜・残月
6楼-- · 2018-12-31 05:40

From Angular 6.1 you can use the keyvalue pipe:

<div *ngFor="let item of testObject | keyvalue">
    Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</div>

But it has the inconvenient that sorts the resulting list by the key value. If you need something neutral:

@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;
  }
}

Don't forget to specify the pure:false pipe attribute. In this case, the pipe is invoked on each change-detection cycle, even if the input reference has not changed (so is the case when you add properties to an object).

查看更多
浮光初槿花落
7楼-- · 2018-12-31 05:40

You have to do it like this for now, i know not very efficient as you don't want to convert the object you receive from firebase.

    this.af.database.list('/data/' + this.base64Email).subscribe(years => {
        years.forEach(year => {

            var localYears = [];

            Object.keys(year).forEach(month => {
                localYears.push(year[month])
            });

            year.months = localYears;

        })

        this.years = years;

    });
查看更多
登录 后发表回答