Pertanyaan Iterate over object dalam Angular


Saya mencoba melakukan beberapa hal di Angular 2 Alpha 28, dan saya mengalami masalah dengan kamus dan NgFor.

Saya memiliki antarmuka dalam TypeScript yang terlihat seperti ini:

interface Dictionary {
    [ index: string ]: string
}

Dalam JavaScript ini akan menerjemahkan ke objek yang dengan data mungkin terlihat seperti ini:

myDict={'key1':'value1','key2':'value2'}

Saya ingin mengulangi ini dan mencoba ini:

<div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div>

Tetapi tidak berhasil, tidak ada yang di bawah ini yang berhasil:

<div *ngFor="#value of myDict">{{value}}</div>
<div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div>

Dalam semua kasus saya mendapatkan kesalahan seperti "Token tak terduga" atau "Tidak dapat menemukan 'objek pendukung pipa yang mendukung iterableDiff"

Apa yang kulewatkan di sini? Apakah ini tidak mungkin lagi? (Sintaks pertama bekerja di Angular 1.x) atau sintaks berbeda untuk iterasi atas objek?


75
2017-07-18 11:30


asal


Jawaban:


Tampaknya mereka tidak ingin mendukung sintaks dari ng1.

Menurut Miško Hevery (referensi):

Peta tidak memiliki pesanan dalam kunci dan karenanya iterasi tidak dapat diprediksi.   Ini didukung dalam ng1, tetapi kami pikir itu adalah kesalahan dan tidak akan   didukung di NG2

Rencananya adalah memiliki pipa mapToIterable

<div *ngFor"var item of map | mapToIterable">

Jadi untuk iterate atas objek Anda, Anda akan perlu menggunakan "pipa". Saat ini tidak ada pipa diimplementasikan yang melakukan itu.

Sebagai solusinya, berikut ini adalah contoh kecil yang mengulangi kunci:

Komponen:

import {Component} from 'angular2/core';

@Component({
  selector: 'component',
  templateUrl: `
       <ul>
       <li *ngFor="#key of keys();">{{key}}:{{myDict[key]}}</li>
       </ul>
  `
})
export class Home {
  myDict : Dictionary;
  constructor() {
    this.myDict = {'key1':'value1','key2':'value2'};
  }

  keys() : Array<string> {
    return Object.keys(this.myDict);
  }
}

interface Dictionary {
    [ index: string ]: string
}

68
2017-07-21 11:22



coba gunakan pipa ini

@Pipe({ name: 'values',  pure: false })
export class ValuesPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value).map(key => value[key]);
  }
}

<div *ngFor="#value of object | values"> </div>

60
2017-12-03 19:26



2018 Pembaruan:

Seperti jawaban yang lain telah disebutkan, itu tidak didukung dalam ngx, jadi inilah solusi dengan pasangan nilai-kunci:

Pipa:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
  transform(dict: Object) {
    var a = [];
    for (var key in dict) {
      if (dict.hasOwnProperty(key)) {
        a.push({key: key, val: dict[key]});
      }
    }
    return a;
  }
}

Penggunaan:

<div *ngFor="let keyValuePair of someObject | mapToIterable">
  This is the key {{keyValuePair.key}} and this is the value {{keyValuePair.val}}.
</div>

Contoh Stackblitz: https://stackblitz.com/edit/map-to-iterable-pipe


31
2018-02-08 01:14



Selain jawaban @ obscur, berikut adalah contoh bagaimana Anda dapat mengakses keduanya key dan value dari @View.

Pipa:

@Pipe({
   name: 'keyValueFilter'
})

export class keyValueFilterPipe {
    transform(value: any, args: any[] = null): any {

        return Object.keys(value).map(function(key) {
            let pair = {};
            let k = 'key';
            let v = 'value'


            pair[k] = key;
            pair[v] = value[key];

            return pair;
        });
    }

}

Melihat:

<li *ngFor="#u of myObject | 
keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>

Jadi jika objek itu terlihat seperti:

myObject = {
    Daario: Naharis,
    Victarion: Greyjoy,
    Quentyn: Ball
}

Hasil yang dihasilkan adalah:

Nama depan: Daario
Nama Belakang: Naharis

Nama depan: Victarion
Nama Belakang: Greyjoy

Nama depan: Quentyn
Nama Belakang: Bola


18
2018-03-03 18:14



Menambah SimonHawesome's jawaban yang sangat baik. Saya telah membuat versi ringkas yang menggunakan beberapa fitur naskah baru. Saya menyadari bahwa versi SimonHawesome sengaja dikenali untuk menjelaskan rincian yang mendasari. Saya juga menambahkan pemeriksaan awal sehingga pipa berfungsi falsy nilai-nilai. Misalnya, jika peta itu null.

Perhatikan bahwa menggunakan transformasi iterator (seperti yang dilakukan di sini) dapat lebih efisien karena kita tidak perlu mengalokasikan memori untuk array sementara (seperti yang dilakukan pada beberapa jawaban lainnya).

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

@Pipe({
    name: 'mapToIterable'
})
export class MapToIterable implements PipeTransform {
    transform(map: { [key: string]: any }, ...parameters: any[]) {
        if (!map)
            return undefined;
        return Object.keys(map)
            .map((key) => ({ 'key': key, 'value': map[key] }));
    }
}

12
2018-05-27 09:15



Berikut adalah variasi pada beberapa jawaban di atas yang mendukung beberapa transformasi (keyval, key, value):

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

type Args = 'keyval'|'key'|'value';

@Pipe({
  name: 'mapToIterable',
  pure: false
})
export class MapToIterablePipe implements PipeTransform {
  transform(obj: {}, arg: Args = 'keyval') {
    return arg === 'keyval' ?
        Object.keys(obj).map(key => ({key: key, value: obj[key]})) :
      arg === 'key' ?
        Object.keys(obj) :
      arg === 'value' ?
        Object.keys(obj).map(key => obj[key]) :
      null;
  }
}

Pemakaian

map = {
    'a': 'aee',
    'b': 'bee',
    'c': 'see'
}

<div *ngFor="let o of map | mapToIterable">{{o.key}}: {{o.value}}</div>
  <div>a: aee</div>
  <div>b: bee</div>
  <div>c: see</div>

<div *ngFor="let o of map | mapToIterable:'keyval'">{{o.key}}: {{o.value}}</div>
  <div>a: aee</div>
  <div>b: bee</div>
  <div>c: see</div>

<div *ngFor="let k of map | mapToIterable:'key'">{{k}}</div>
  <div>a</div>
  <div>b</div>
  <div>c</div>

<div *ngFor="let v of map | mapToIterable:'value'">{{v}}</div>
  <div>aee</div>
  <div>bee</div>
  <div>see</div>

9
2018-01-11 22:32



Saya memiliki masalah serupa, membangun sesuatu untuk objek dan Maps.

import { Pipe } from 'angular2/core.js';

/**
 * Map to Iteratble Pipe
 * 
 * It accepts Objects and [Maps](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
 * 
 * Example:
 * 
 *  <div *ngFor="#keyValuePair of someObject | mapToIterable">
 *    key {{keyValuePair.key}} and value {{keyValuePair.value}}
 *  </div>
 * 
 */
@Pipe({ name: 'mapToIterable' })
export class MapToIterable {
  transform(value) {
    let result = [];
    
    if(value.entries) {
      for (var [key, value] of value.entries()) {
        result.push({ key, value });
      }
    } else {
      for(let key in value) {
        result.push({ key, value: value[key] });
      }
    }

    return result;
  }
}


4
2018-04-13 23:27



Sudut 2.x && Sudular 4.x tidak mendukung ini di luar kotak

Anda dapat menggunakan dua pipa ini untuk mengulanginya dengan baik kunci atau dengan nilai.

Kunci pipa:

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

@Pipe({
  name: 'keys',
  pure: false
})
export class KeysPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value)
  }
}

Nilai pipa:

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

@Pipe({
  name: 'values',
  pure: false
})
export class ValuesPipe implements PipeTransform {
  transform(value: any, args: any[] = null): any {
    return Object.keys(value).map(key => value[key])
  }
}

Bagaimana cara menggunakan:

let data = {key1: 'value1', key2: 'value2'}

<div *ngFor="let key of data | keys"></div>
<div *ngFor="let value of data | values"></div>

3
2018-05-30 06:15