Як виконати ітерацію об'єктних ключів за допомогою * ngFor


76

Я хочу виконати ітерацію [об'єкт об'єкта] за допомогою * ngFor в Angular 2.

Проблема полягає в тому, що об'єкт не є масивом об'єкта, а об'єктом об'єкта, який містить подальші об'єкти.

{

  "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

Я не бачу якихось - яких труднощів тут, якщо у вас є масив об'єктів, ви можете itterate з ngFor легко
Milad

@Umar: Не могли б ви поставити два з них, щоб ми могли отримати загальну картину?
Мілад,

@Milad, що не є масивом об'єктів, це головна проблема. це цілий упакований об'єкт, який містить додатковий об'єкт, наприклад дані-> малюнок-> великий палець-> URL я хочу отримати доступ до thumb0-> url
Umar Rasheed

Відповіді:


168

Кутова 6.0.0

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

введено a 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?


дякую за відповідь! за цього підходу я вже можу отримати доступ до картинки-> url, але не зображення-> thumb-> url. як далі входити в нього .. <div * ngFor = "let key of posts | objs"> <ion-avatar item-left * ngIf = "key == 'picture'"> <img [src] = "posts [ key] .url "> <- url-зображення тут потрібна URL-адреса великого пальця, яка знаходиться далі в об'єкті зображення </ion-avatar> </div>
Умар Рашид,

На жаль, я не розумію, про що йдеться у коментарі. Чому ви не можете отримати доступ до зображення-> великого пальця-> URL-адреси? Можливо [src]="posts[key].thumb.url"?
Günter Zöchbauer

Ласкаво просимо. Радий почути, що ви можете змусити це працювати.
Günter Zöchbauer

у мене є інша відповідь json, я використовую той же підхід, що і вище, але отримую помилку, не можу перетворити невизначений або нульовий на об'єкт. ось відповідь json. {"id": 1, "food": "McDonalds Sharebox Chicken Plus (Drink - Coke)", "user_id": 834, "rating_id": null, "runner_id": 43,}
Умар Рашид,

2
Було додано 6.1.0
Günter Zöchbauer

45

Я думаю, що найелегантніший спосіб зробити це - використовувати javascript Object.keysтаким чином (я спочатку запровадив конвеєр для цього, але для мене це просто ускладнило мою непотрібну роботу):

у об’єкті передачі компонента до шаблону:

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>

Якщо у вас багато підоб’єктів, вам слід створити компонент, який надрукує об’єкт за вас. Друкуючи значення та ключі як завгодно, і на підоб'єкті, викликаючи це рекурсивно.

Тут ви можете знайти демонстраційний стек для обох методів.


Не впевнений, що це ідеальний спосіб! Але це працює. Здається, оптимальне рішення для моєї вимоги.
Aravind

Це ідеально! Я шукав це протягом останніх 30 хвилин! Працює точно так, як очікувалось, на такому об'єкті: [nosings: {a: 1, b: 2}, komunal__carpets: {a: 1, b: 2, c: 3}]
Fery Kaszoni,

10

Я знаю, що на це питання вже відповіли, але у мене є одне рішення для цього самого.

Ви також можете використовувати Object.keys()всередині, *ngForщоб отримати необхідний результат.

Я створив демонстраційне відео про стекбліц . Сподіваюся, це допоможе / допоможе вам / іншим.

КОД СНИППЕТ

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

stackblitz.com/edit/angular-iterator-stringobj чи можете ви подивитися на це
Нарендар


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"

я зробив із цим, проблема полягає у ngДля використання з масивом об'єкта, у моєму випадку це не масив об'єкта, об'єкт в об'єкт, а потім подальший об'єкт в об'єкт, як ці дані-> малюнок-> великий палець-> url.
Умар Рашид

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>

2

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.