如何使用* ngFor迭代对象键


76

我想在Angular 2中使用* ngFor迭代[object object]。

问题是对象不是对象数组,而是包含更多对象的对象对象。

{

  "data": {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "03215110224",
    "role": null,
    "email": "test@example.com",
    "picture": **{ <-- I want to get thumb: url but not able to fetch that**
      "url": null,
      "thumb": {
        "url": null
      }
    },
    "address": "Nishtar Colony",
    "city_id": 2,
    "provider": "email",
    "uid": "test@example.com"
  }
}

我知道我们可以使用管道来迭代对象,但是如何在对象之间进一步迭代意味着data-> picture-> thum:url



您可能正在寻找递归函数。
JoeriShoeby

我在这里没有任何困难,如果您有对象数组,则可以使用ngFor轻松完成操作
Milad

@Umar:请问你可以放两个吗,这样我们可以有一个更大的图景?
Milad

@Milad不是对象数组,这是主要问题。那是整个打包的对象,其中包含其他对象,例如data-> picture-> thumb-> url。我想访问thumb0-> url
Umar Rasheed

Answers:


165

角6.0.0

https://github.com/angular/angular/blob/master/CHANGELOG.md#610-2018-07-25

介绍了 KeyValuePipe

另请参阅https://angular.io/api/common/KeyValuePipe

@Component({
  selector: 'keyvalue-pipe',
  template: `<span>
    <p>Object</p>
    <div *ngFor="let item of object | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
    <p>Map</p>
    <div *ngFor="let item of map | keyvalue">
      {{item.key}}:{{item.value}}
    </div>
  </span>`
})
export class KeyValuePipeComponent {
  object: {[key: number]: string} = {2: 'foo', 1: 'bar'};
  map = new Map([[2, 'foo'], [1, 'bar']]);
}

原版的

你可以用管子

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

另请参阅如何使用* ngFor迭代对象键?


感谢您的回复!通过这种方法,现在我可以访问picture-> url,但不能访问picture-> thumb-> url。如何进一步迭代到它。 key] .url“> <-图片URL在这里想要缩略图URL进一步成为图片对象</ ion-avatar> </ div>
Umar Rasheed

抱歉,我不知道该评论是关于什么的。为什么不能访问picture-> thumb-> url?也许[src]="posts[key].thumb.url"吧?
君特Zöchbauer

别客气。很高兴听到您可以使用它。
君特Zöchbauer

我有另一个json响应,我使用的是与上述相同的方法,但出现错误,无法将未定义或null转换为对象。这是一个json响应。{“ id”:1,“ food”:“ McDonalds Sharebox Chicken Plus(Drink-Coke)”,“ user_id”:834,“ rating_id”:null,“ runner_id”:43,}
Umar Rasheed

2
它补充6.1.0
君特Zöchbauer

43

我认为最优雅的方法是使用Object.keys像这样的javascript (我首先为此实现了一个管道,但是对我来说,这使我的工作变得不必要了):

在组件中将对象传递给模板:

Object = Object;

然后在模板中:

<div *ngFor="let key of Object.keys(objs)">
   my key: {{key}}
   my object {{objs[key] | json}} <!-- hier I could use ngFor again with Object.keys(objs[key]) -->
</div>

如果您有很多子对象,则应创建一个将为您打印该对象的组件。通过根据需要在递归调用自身的子对象上打印值和键。

海尔你可以找到这两种方法的stackblitz演示。


不知道这是否是理想的方法!但这有效。似乎是满足我需求的最佳解决方案。
Aravind

太棒了!我过去30分钟一直在寻找它!完全按预期在这样的对象上工作:[鼻子:{a:1,b:2},communal_carpets:{a:1,b:2,c:3}]
Fery Kaszoni

10

我知道这个问题已经回答,但是我有一个解决方案。

您还可以Object.keys()在中使用*ngFor以获得所需的结果。

我已经在stackblitz上创建了一个演示。希望这对您/其他人有所帮助/指南。

代码片段

HTML代码

<div *ngFor="let key of Object.keys(myObj)">
  <p>Key-> {{key}} and value is -> {{myObj[key]}}</p>
</div>

.ts文件代码

Object = Object;

myObj = {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "1234567890",
    "role": null,
    "email": "test@example.com",
    "picture": {
        "url": null,
        "thumb": {
            "url": null
        }
    },
    "address": "XYZ Colony",
    "city_id": 2,
    "provider": "email",
    "uid": "test@example.com"
}



9

您必须创建自定义管道。

import { Injectable, Pipe } from '@angular/core';
@Pipe({
   name: 'keyobject'
})
@Injectable()
export class Keyobject {

transform(value, args:string[]):any {
    let keys = [];
    for (let key in value) {
        keys.push({key: key, value: value[key]});
    }
    return keys;
}}

然后在* ngFor中使用它

*ngFor="let item of data | keyobject"

我已经完成了,问题是ngFor与对象数组一起使用,在我的情况下不是对象数组,将对象转换为对象,然后进一步将对象转换为对象,例如data-> picture-> thumb-> url。
Umar Rasheed

3

1.创建一个自定义管道以获取密钥。

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

@Pipe({
  name: 'keys'
})
export class KeysPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return Object.keys(value);
  }
}
  1. 在角度模板文件中,可以使用* ngFor并遍历对象对象
<div class ="test" *ngFor="let key of Obj | keys">
    {{key}}
    {{Obj[key].property}
<div>

1

对于这种情况,Angular现在具有一种迭代对象,称为Set。当我找到这个问题进行搜索时,它符合我的需求。创建集合,就像将其“推”到数组中一样“添加”到集合中,然后像数组一样将其放入ngFor中。没有管道或任何东西。

this.myObjList = new Set();

...

this.myObjList.add(obj);

...

<ul>
   <li *ngFor="let object of myObjList">
     {{object}}
   </li>
</ul>

您使用什么类型myObjList?当我尝试时,我的短毛猫说:Type 'Set<any>' is not assignable to type 'IMyInterface'
迭戈·奥尔蒂斯

0

如果您map()在响应中使用运算符,则可以将toArray()运算符链接到该运算符...那么您应该能够遍历新创建的数组...至少对我有用:)


对象不使用toArray
SeanMC '18

-5

我会这样做:

<li *ngFor="let item of data" (click)='onclick(item)'>{{item.picture.url}}</li>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.