So iterieren Sie Objektschlüssel mit * ngFor

76

Ich möchte [Objektobjekt] mit * ngFor in Angular 2 iterieren.

Das Problem ist, dass das Objekt kein Array eines Objekts ist, sondern ein Objekt des Objekts, das weitere Objekte enthält.

{

  "data": {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "03215110224",
    "role": null,
    "email": "[email protected]",
    "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": "[email protected]"
  }
}

Ich weiß, dass wir Pipe verwenden können, um das Objekt zu iterieren, aber wie wir weiter von Objekt zu Objekt iterieren können, bedeutet Daten-> Bild-> Thum: URL .

Umar Rasheed
quelle
1
Dup von stackoverflow.com/questions/37046138/…
Günter Zöchbauer
Sie suchen vielleicht nach rekursiven Funktionen.
JoeriShoeby
Ich sehe hier keine Schwierigkeiten, wenn Sie eine Reihe von Objekten haben, können Sie mit ngFor leicht iterieren
Milad
@Umar: Könnten Sie bitte zwei davon einfügen, damit wir ein größeres Bild haben?
Milad
@Milad, das kein Array von Objekten ist, das ist das Hauptproblem. Das ist ein ganzes gepacktes Objekt, das weitere Objekte wie Daten-> Bild-> Daumen-> URL enthält. Ich möchte auf die thumb0-> url
Umar Rasheed

Antworten:

165

Winkel 6.0.0

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

eingeführt a KeyValuePipe

Siehe auch 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']]);
}

Original

Sie können eine Pfeife verwenden

@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">

Siehe auch So iterieren Sie Objektschlüssel mit * ngFor?

Günter Zöchbauer
quelle
danke für die Antwort! Durch diesen Ansatz kann ich jetzt auf die Bild-> URL zugreifen, aber nicht auf die Bild-> Daumen-> URL. wie man weiter hinein iteriert .. <div * ngFor = "Schlüssel der Beiträge lassen | objs"> <ion-avatar item-left * ngIf = "Schlüssel == 'Bild'"> <img [src] = "Beiträge [ Schlüssel] .url "> <- Bild-URL hier wollen Daumen-URL, die weiter in Bild-Objekt </ ion-avatar> </ div>
Umar Rasheed
Entschuldigung, ich verstehe nicht, worum es in dem Kommentar geht. Warum können Sie nicht auf Bild-> Daumen-> URL zugreifen? Vielleicht [src]="posts[key].thumb.url"?
Günter Zöchbauer
Bitte. Ich bin froh zu hören, dass du es schaffen könntest.
Günter Zöchbauer
Ich habe eine andere JSON-Antwort. Ich verwende den gleichen Ansatz wie oben, erhalte jedoch den Fehler. Undefiniert oder Null kann nicht in Objekt konvertiert werden. Hier ist eine Antwort von json. {"id": 1, "food": "McDonalds Sharebox Chicken Plus (Getränk - Cola)", "user_id": 834, "Rating_id": null, "running_id": 43,}
Umar Rasheed
2
Es wurde hinzugefügt 6.1.0
Günter Zöchbauer
43

Ich denke, der eleganteste Weg, dies zu tun, besteht darin, das Javascript Object.keyswie folgt zu verwenden (ich hatte zuerst eine Pipe dafür implementiert, aber für mich hat es meine Arbeit nur unnötig kompliziert gemacht):

Übergeben Sie im Objekt Objekt an Vorlage:

Object = Object;

dann in der Vorlage:

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

Wenn Sie viele Unterobjekte haben, sollten Sie eine Komponente erstellen, die das Objekt für Sie druckt. Durch Drucken der Werte und Schlüssel nach Belieben und in einem Unterobjekt, das sich selbst rekursiv aufruft.

Hier finden Sie eine Stackblitz-Demo für beide Methoden.

Sheki
quelle
Ich bin mir nicht sicher, ob dies der ideale Weg ist! Aber es funktioniert. Scheint eine optimale Lösung für meine Anforderung zu sein.
Aravind
Dies ist perfekt! Ich habe in den letzten 30 Minuten danach gesucht! Funktioniert genau wie erwartet für ein Objekt wie dieses: [nosings: {a: 1, b: 2}, communal_carpets: {a: 1, b: 2, c: 3}]
Fery Kaszoni
10

Ich weiß, dass diese Frage bereits beantwortet ist, aber ich habe eine Lösung dafür.

Sie können auch Object.keys()inside of verwenden *ngFor, um das gewünschte Ergebnis zu erhalten.

Ich habe eine Demo auf stackblitz erstellt . Ich hoffe, dies wird Ihnen / anderen helfen.

CODE-AUSZUG

HTML Quelltext

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

.ts Dateicode

Object = Object;

myObj = {
    "id": 834,
    "first_name": "GS",
    "last_name": "Shahid",
    "phone": "1234567890",
    "role": null,
    "email": "[email protected]",
    "picture": {
        "url": null,
        "thumb": {
            "url": null
        }
    },
    "address": "XYZ Colony",
    "city_id": 2,
    "provider": "email",
    "uid": "[email protected]"
}
Krishna Rathore
quelle
9

Sie müssen eine benutzerdefinierte Pipe erstellen.

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

Und dann verwenden Sie es in Ihrem * ngFor

*ngFor="let item of data | keyobject"
Igor Janković
quelle
Ich habe damit fertig, das Problem ist ngFür die Verwendung mit Array von Objekt, in meinem Fall, dass nicht Array von Objekt, Objekt in Objekt, dann weiter Objekt in Objekt wie diese Daten-> Bild-> Daumen-> URL.
Umar Rasheed
3

1.Erstellen Sie eine benutzerdefinierte Pipe, um Schlüssel abzurufen.

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. In einer eckigen Vorlagendatei können Sie * ngFor verwenden und über Ihr Objektobjekt iterieren
<div class ="test" *ngFor="let key of Obj | keys">
    {{key}}
    {{Obj[key].property}
<div>
skipper21
quelle
1

Angular verfügt jetzt über eine Art iteriertes Objekt für genau dieses Szenario, das als Set bezeichnet wird. Es passte zu meinen Bedürfnissen, als ich diese Frage suchend fand. Sie erstellen das Set, "fügen" es hinzu, als würden Sie es in ein Array "pushen", und legen es wie ein Array in einem ngFor ab. Keine Rohre oder so.

this.myObjList = new Set();

...

this.myObjList.add(obj);

...

<ul>
   <li *ngFor="let object of myObjList">
     {{object}}
   </li>
</ul>
SeanMC
quelle
Für welchen Typ verwenden Sie myObjList? Als ich es versuchte, sagte mein Linter:Type 'Set<any>' is not assignable to type 'IMyInterface'
Diego Ortiz
0

Wenn Sie map()für Ihre Antwort einen Operator verwenden, können Sie möglicherweise einen toArray()Operator daran verketten ... dann sollten Sie in der Lage sein, das neu erstellte Array zu durchlaufen ... zumindest hat das bei mir funktioniert :)

Hrx
quelle
Objekt verwendet nicht toArray
SeanMC
-5

Ich würde das tun:

<li *ngFor="let item of data" (click)='onclick(item)'>{{item.picture.url}}</li>
arn-arn
quelle