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:23

Update

In 6.1.0-beta.1 KeyValuePipe was introduced https://github.com/angular/angular/pull/24319

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

Plunker Example

Previous version

Another approach is to create NgForIn directive that will be used like:

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

Plunker Example

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);
    }
  }
}
查看更多
裙下三千臣
3楼-- · 2018-12-31 05:27

change demo type to array or iterate over your object and push to another array

public details =[];   
Object.keys(demo).forEach(key => {
      this.details.push({"key":key,"value":demo[key]);
    });

and from html:

<div *ngFor="obj of details">
  <p>{{obj.key}}</p>
  <p>{{obj.value}}</p>
  <p></p>
</div>
查看更多
裙下三千臣
4楼-- · 2018-12-31 05:29

As in latest release of Angular (v6.1.0) , Angular Team has added new built in pipe for the same named as keyvalue pipe to help you iterate through objects, maps, and arrays, in the common module of angular package. For example -

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

Working Forked Example

check it out here for more useful information -

If you are using Angular v5 or below or you want to achieve using pipe follow this answer

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

@Marton had an important objection to the accepted answer on the grounds that the pipe creates a new collection on each change detection. I would instead create an HtmlService which provides a range of utility functions which the view can use as follows:

@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楼-- · 2018-12-31 05:32

Have Object.keys accessible in the template and use it in *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(){}
}
查看更多
宁负流年不负卿
7楼-- · 2018-12-31 05:33

I think Object.keys is the best solution to this problem. For anyone that comes across this answer and is trying to find out why Object.keys is giving them ['0', '1'] instead of ['key1', 'key2'], a cautionary tale - beware the difference between "of" and "in":

I was already using Object.keys, something similar to this:

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

However, instead of

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

I had inadvertently wrote

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

which "worked" perfectly fine without any error and returned

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

That cost me about 2 hours googling and cursing..

(slaps forehead)

查看更多
登录 后发表回答