วนซ้ำวัตถุใน Angular


131

ฉันกำลังพยายามทำบางสิ่งใน Angular 2 Alpha 28 และกำลังมีปัญหากับพจนานุกรมและ NgFor

ฉันมีอินเทอร์เฟซใน TypeScript ที่มีลักษณะดังนี้:

interface Dictionary {
    [ index: string ]: string
}

ใน JavaScript สิ่งนี้จะแปลเป็นวัตถุที่มีข้อมูลอาจมีลักษณะดังนี้:

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

ฉันต้องการทบทวนสิ่งนี้และลองทำสิ่งนี้:

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

แต่ไม่เป็นประโยชน์ไม่มีข้อใดต่อไปนี้ทำงานได้:

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

ในทุกกรณีฉันได้รับข้อผิดพลาดเช่น "โทเค็นที่ไม่คาดคิด" หรือ "ไม่พบวัตถุที่สนับสนุนไปป์" iterableDiff ""

ฉันพลาดอะไรไปที่นี่? เป็นไปไม่ได้อีกแล้วหรือ (ไวยากรณ์แรกทำงานใน Angular 1.x) หรือไวยากรณ์แตกต่างกันสำหรับการวนซ้ำบนวัตถุหรือไม่?


"พจนานุกรม" คืออะไร? ฉันไม่เคยเห็นหรือได้ยินคำนั้นในบริบท JavaScript, Angular หรือ TypeScript Y

พจนานุกรมหมายถึงแผนที่ฉันคิดว่าคำนี้ไม่ได้ใช้เลยในบริบท JS แต่ใช้ใน Python หรือ Ruby
Cesar Jr Rodriguez

2
ฉันคิดว่าคำตอบของ @bersling คือคำตอบที่ถูกต้องสำหรับคำถามนี้
Joshua Kissoon

1
กรุณาทำเครื่องหมายคำตอบที่ถูกต้องดีกว่า bersling ถูกต้อง
activedecay

คำตอบ:


87

ดูเหมือนว่าพวกเขาไม่ต้องการรองรับไวยากรณ์จาก ng1

อ้างอิงจากMiško Hevery ( อ้างอิง ):

Maps ไม่มีคำสั่งในคีย์และด้วยเหตุนี้การทำซ้ำจึงไม่สามารถคาดเดาได้ สิ่งนี้ได้รับการสนับสนุนใน ng1 แต่เราคิดว่ามันเป็นข้อผิดพลาดและจะไม่รองรับใน NG2

แผนคือจะต้องมีท่อ mapToIterable

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

ดังนั้นในการวนซ้ำวัตถุของคุณคุณจะต้องใช้ "ไปป์" ขณะนี้ไม่มีการดำเนินการท่อที่ทำเช่นนั้น

เพื่อเป็นการแก้ปัญหาชั่วคราวนี่คือตัวอย่างเล็ก ๆ ที่วนซ้ำบนคีย์:

ส่วนประกอบคือ:

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
}

1
ฉันกำลังลองทำแบบเดียวกันกับวัตถุที่keyเป็นnumberและvalueเป็นstringแต่เชิงมุมมีข้อผิดพลาดในการขว้างปาexpression has changed after it was checked? ทำไมถึงมีความคิด?
Pardeep Jain

ใช่สิ่งนี้ก็เกิดขึ้นกับฉันเช่นกัน และเช่นเดียวกันถ้าฉันใช้โซลูชันของ @ obsur ด้วย
user2294382

1
โปรดดูคำตอบของ bersling เพราะมีวิธีแก้ปัญหาเล็กน้อยสำหรับ angular 7 ล่าสุด
activedecay

157

คำตอบเชิงมุม 6.1.0+

ใช้keyvalueท่อในตัวดังนี้:

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

หรือเช่นนี้:

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

อยู่ที่ไหนmySortingFunctionใน.tsไฟล์ของคุณตัวอย่างเช่น:

mySortingFunction = (a, b) => {
  return a.key > b.key ? -1 : 1;
}

Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value

คุณไม่จำเป็นต้องลงทะเบียนสิ่งนี้ในโมดูลใด ๆ เนื่องจากท่อ Angular ทำงานนอกกรอบในเทมเพลตใด ๆ

นอกจากนี้ยังทำงานสำหรับจาวาสคริ-แผนที่


คุณควรเพิ่มimplements PipeTransformคำจำกัดความของคลาส (ดูangular.io/guide/pipes#custom-pipes )
toioski

1
@toioski ขอบคุณฉันได้เพิ่มและอัปเดตไวยากรณ์ใหม่ของ for loop แล้ว
บ้าคลั่ง

คำตอบที่ดีใช้เพื่อ ngFor my Dictionary ฉันต้องทำ keyValuePair.val [0] แม้ว่าค่าของฉันจะลงเอยด้วย [{}] และไม่ใช่ {}
jhhoff02

1
มีข้อได้เปรียบมากกว่านี้return Object.keys(dict).map(key => ({key, val: dict[key]}))หรือไม่?
Justin Morgan

ฉันไม่เห็นเลยจริง ๆ แล้วฉันจะใช้วิธีของคุณ!
บ้าคลั่ง

72

ลองใช้ท่อนี้

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

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

5
ยอดเยี่ยมและถ้าฉันต้องการเก็บการอ้างอิงถึงคีย์ฉันจะแมปวัตถุด้วยทั้งคีย์และค่าแทน ฉันหวังว่าฉันจะทำเครื่องหมายคำตอบหลาย ๆ คำตอบเป็นคำตอบที่ยอมรับได้เนื่องจากนี่เป็นวิธีแก้ปัญหาของฉันในขณะที่คำตอบที่ทำเครื่องหมายไว้คือคำตอบสำหรับคำถามของฉัน
Rickard Staaf

1
@obscur - หากฉันทำตามข้างบนตอนนี้ฉันได้รับข้อผิดพลาด "นิพจน์เปลี่ยนไปหลังจากที่ตรวจสอบแล้ว" โดยใช้ angular2.beta.0.0 ความคิดใด ๆ ?
user2294382

นั่นเป็นเพราะบริสุทธิ์: เท็จต้องการการตรวจจับการเปลี่ยนแปลงกลยุทธ์ที่จะฉีด
Judson Terrell

1
ทำไมตั้งค่าให้ไม่บริสุทธิ์?
tom10271

นี้ทำงานได้ดีสำหรับฉัน. สิ่งเดียวคือฉันไม่สามารถใช้ # ใน ngFor ได้ ใช้ let แทน
MartinJH

19

นอกจากคำตอบของ @ obcur แล้วนี่คือตัวอย่างวิธีการเข้าถึงทั้งจากkeyและvalueจาก @View

ท่อ:

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

}

ดู:

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

ดังนั้นหากวัตถุมีลักษณะดังนี้:

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

ผลลัพธ์ที่สร้างขึ้นจะเป็น:

ชื่อจริง: Daario
นามสกุล: Naharis

ชื่อจริง: Victarion
นามสกุล: Greyjoy

ชื่อจริง: Quentyn
นามสกุล: Ball


2
เพียงสิ่งหนึ่งที่จะพูดถึงคุณจำเป็นต้องเปลี่ยนมุมมอง: <li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>เป็น +1 จากฉัน
sib10

รหัสภายในฟังก์ชันแผนที่ของคุณสามารถทำให้ง่ายขึ้นได้ดังนี้ return { 'key' : key, 'value' : value[key] };
Makotosan

17

อัปเดต: Angular กำลังให้ท่อสำหรับการลากผ่านวัตถุ json ผ่านkeyvalue:

<div *ngFor="let item of myDict | keyvalue">
  {{item.key}}:{{item.value}}
</div>

การสาธิตการทำงานและสำหรับรายละเอียดเพิ่มเติมอ่าน


ก่อนหน้านี้ (สำหรับรุ่นเก่ากว่า): จนถึงตอนนี้คำตอบที่ดีที่สุด / สั้นที่สุดที่ฉันพบคือ (ไม่มีตัวกรองท่อหรือฟังก์ชันที่กำหนดเองจากด้านคอมโพเนนต์)

ด้านส่วนประกอบ:

objectKeys = Object.keys;

ด้านแม่แบบ:

<div *ngFor='let key of objectKeys(jsonObj)'>
   Key: {{key}}

    <div *ngFor='let obj of jsonObj[key]'>
        {{ obj.title }}
        {{ obj.desc }}
    </div>

</div>

การสาธิตการทำงาน


1
let item of myDict | keyvalueสิ่งนี้ช่วยแก้ปัญหาของฉันได้
Silambarasan RD

13

เพิ่มไป SimonHawesome ของคำตอบที่ดี ฉันได้สร้างเวอร์ชันรวบรัดซึ่งใช้คุณสมบัติใหม่ ๆ ของ typescript ฉันตระหนักดีว่าเวอร์ชันของ SimonHawesome นั้นมีเจตนาที่จะอธิบายรายละเอียดพื้นฐาน ฉันยังได้เพิ่มการตรวจสอบในช่วงต้นออกเพื่อให้ท่อทำงานสำหรับfalsyค่า เช่นถ้าเป็นแผนที่nullเช่นถ้าเป็นแผนที่

โปรดทราบว่าการใช้การแปลงตัววนซ้ำ (ดังที่ทำที่นี่) จะมีประสิทธิภาพมากกว่าเนื่องจากเราไม่จำเป็นต้องจัดสรรหน่วยความจำสำหรับอาร์เรย์ชั่วคราว (ดังที่ทำในคำตอบอื่น ๆ บางส่วน)

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

3
รักกระทู้นี้ด้วยการสร้างความคิดเห็นหนึ่งด้านบนของอีกกระทู้! ฉันกำลังจะเขียนสิ่งเดียวกันเมื่อเห็นรหัสของคุณ
เดวิด

3
สิ่งเดียวในโซลูชันนี้: ควรใช้PipeTransform
iRaS

@iRaS จุดดี. ฉันได้อัปเดตคำตอบแล้ว ฉันยังส่งคืนไม่ได้กำหนดแทนค่าว่าง
เฟรดเดอริคอาลุนด์

9

นี่คือรูปแบบของคำตอบข้างต้นที่รองรับการแปลงหลายรูปแบบ (คีย์เวิร์ดคีย์ค่า):

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

การใช้

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>

1
pure: falseเป็นสิ่งสำคัญมากสำหรับการสะท้อนทันที
FıratKÜÇÜK

4

ฉันมีปัญหาที่คล้ายกันสร้างบางอย่างสำหรับวัตถุและแผนที่

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


1
สิ่งนี้ใช้งานได้ดียกเว้นใน TypeScript คุณควรเพิ่มimplements PipeTransformคำจำกัดความของคลาส
GeorgDangl

3

Angular 2.x && Angular 4.x ไม่รองรับสิ่งนี้นอกกรอบ

คุณสามารถใช้สองท่อเพื่อย้ำทั้งโดยคีย์หรือค่า

ท่อกุญแจ:

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

ท่อค่า:

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])
  }
}

วิธีใช้:

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

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

2

หากมีใครสงสัยว่าจะทำงานกับวัตถุหลายมิติได้อย่างไรนี่คือคำตอบ

สมมติว่าเรามีวัตถุต่อไปนี้ในการให้บริการ

getChallenges() {
    var objects = {};
    objects['0'] = { 
        title: 'Angular2', 
        description : "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
    };

    objects['1'] = { 
        title: 'AngularJS', 
        description : "Lorem Ipsum is simply dummy text of the printing and typesetting industry."
    };

    objects['2'] = { 
        title: 'Bootstrap',
        description : "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
    };
    return objects;
}

ในส่วนประกอบเพิ่มฟังก์ชันต่อไปนี้

challenges;

constructor(testService : TestService){
    this.challenges = testService.getChallenges();
}
keys() : Array<string> {
    return Object.keys(this.challenges);
}

สุดท้ายในมุมมองทำตาม

<div *ngFor="#key of keys();">
    <h4 class="heading">{{challenges[key].title}}</h4>
    <p class="description">{{challenges[key].description}}</p>
</div>

2

ฉันฉีกขนของฉันออกด้วยการพยายามแยกวิเคราะห์และใช้ข้อมูลที่ส่งคืนในรูปแบบการเรียกแบบสอบถาม JSON / api ฉันไม่แน่ใจว่าฉันผิดพลาดตรงไหนฉันรู้สึกเหมือนฉันวนเวียนหาคำตอบมาหลายวันไล่ตามรหัสข้อผิดพลาดต่างๆเช่น:

"ไม่พบวัตถุรองรับท่อ" iterableDiff ""

"อาร์เรย์ TYpe ทั่วไปต้องการอาร์กิวเมนต์เดียว"

JSON แยกวิเคราะห์ข้อผิดพลาดและฉันแน่ใจว่าคนอื่น ๆ

ฉันสมมติว่าฉันมีชุดค่าผสมที่ไม่ถูกต้อง

นี่คือข้อมูลสรุปของ gotchas และสิ่งที่ต้องค้นหา

ขั้นแรกให้ตรวจสอบผลลัพธ์ของการเรียก API ของคุณผลลัพธ์ของคุณอาจอยู่ในรูปของวัตถุอาร์เรย์หรืออาร์เรย์ของวัตถุ

ฉันจะไม่เข้าไปมากเกินไปพอที่จะบอกได้ว่าข้อผิดพลาดดั้งเดิมของ OP ที่ไม่สามารถทำซ้ำได้โดยทั่วไปเกิดจากคุณพยายามทำซ้ำวัตถุไม่ใช่ Array

นี่คือผลลัพธ์การดีบักบางส่วนของฉันที่แสดงตัวแปรของทั้งอาร์เรย์และวัตถุ

ดังนั้นโดยทั่วไปเราต้องการทำซ้ำผลลัพธ์ JSON ของเราเราจำเป็นต้องตรวจสอบให้แน่ใจว่าอยู่ในรูปแบบของ Array ฉันลองใช้ตัวอย่างมากมายและบางทีอาจจะรู้ว่าตอนนี้ฉันรู้ว่าบางส่วนจะใช้งานได้จริง แต่วิธีที่ฉันใช้คือการใช้ไปป์และรหัสที่ฉันใช้คือโพสต์โดย t.888

   transform(obj: {[key: string]: any}, arg: string) {
if (!obj)
        return undefined;

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;

จริงๆแล้วฉันคิดว่าสิ่งหนึ่งที่ทำให้ฉันได้รับคือการขาดการจัดการข้อผิดพลาดโดยการเพิ่มการโทร 'ส่งคืนไม่ได้กำหนด' ฉันเชื่อว่าตอนนี้เราอนุญาตให้ส่งข้อมูลที่ไม่คาดคิดไปยังท่อซึ่งเห็นได้ชัดว่าเกิดขึ้นในกรณีของฉัน .

หากคุณไม่ต้องการจัดการกับการโต้แย้งกับท่อ (และดูฉันไม่คิดว่ามันจำเป็นในกรณีส่วนใหญ่) คุณสามารถส่งคืนสิ่งต่อไปนี้

       if (!obj)
          return undefined;
       return Object.keys(obj);

หมายเหตุบางประการเกี่ยวกับการสร้างไปป์และเพจหรือส่วนประกอบที่ใช้ไปป์นั้น

ฉันได้รับข้อผิดพลาดเกี่ยวกับการไม่พบ "name_of_my_pipe" หรือไม่

ใช้คำสั่ง 'ไอออนิกสร้างไปป์' จาก CLI เพื่อให้แน่ใจว่าโมดูลท่อสร้างและอ้างอิงอย่างถูกต้อง ให้แน่ใจว่าคุณเพิ่มสิ่งต่อไปนี้ในหน้า mypage.module.ts

import { PipesModule } from ‘…/…/pipes/pipes.module’;

(ไม่แน่ใจว่าการเปลี่ยนแปลงนี้หากคุณมี custom_module ของคุณเองด้วยคุณอาจต้องเพิ่มลงใน custommodule.module.ts)

หากคุณใช้คำสั่ง 'ไอออนิกสร้างเพจ' เพื่อสร้างเพจของคุณ แต่ตัดสินใจใช้เพจนั้นเป็นเพจหลักอย่าลืมลบการอ้างอิงเพจออกจาก app.module.ts (นี่คือคำตอบอื่นที่ฉันโพสต์เกี่ยวกับเรื่องนั้น https: / /forum.ionicframework.com/t/solved-pipe-not-found-in-custom-component/95179/13?u=dreaser

ในการค้นหาคำตอบของฉันมีหลายวิธีในการแสดงข้อมูลในไฟล์ html และฉันไม่เข้าใจเพียงพอที่จะอธิบายความแตกต่าง คุณอาจพบว่าดีกว่าที่จะใช้กันในบางสถานการณ์

            <ion-item *ngFor="let myPost of posts">
                  <img src="https://somwhereOnTheInternet/{{myPost.ImageUrl}}"/>
                  <img src="https://somwhereOnTheInternet/{{posts[myPost].ImageUrl}}"/>
                  <img [src]="'https://somwhereOnTheInternet/' + myPost.ImageUrl" />
            </ion-item>

อย่างไรก็ตามสิ่งที่ได้ผลที่ทำให้ฉันแสดงทั้งค่าและคีย์มีดังต่อไปนี้:

    <ion-list>  
      <ion-item *ngFor="let myPost of posts  | name_of_pip:'optional_Str_Varible'">

        <h2>Key Value = {{posts[myPost]}} 

        <h2>Key Name = {{myPost}} </h2>

      </ion-item>
   </ion-list>  

เพื่อให้เรียก API ดูเหมือนว่าคุณต้องนำเข้า HttpModule ไปยัง app.module.ts

import { HttpModule } from '@angular/http';
 .
 .  
 imports: [
BrowserModule,
HttpModule,

และคุณต้องใช้ Http ในหน้าที่คุณโทรออก

import {Http} from '@angular/http';

เมื่อทำการเรียก API คุณดูเหมือนจะสามารถเข้าถึงข้อมูลลูก ๆ ได้ (วัตถุหรืออาร์เรย์ภายในอาร์เรย์) 2 วิธีที่แตกต่างกันดูเหมือนจะได้ผล

ทั้งในระหว่างการโทร

this.http.get('https://SomeWebsiteWithAPI').map(res => res.json().anyChildren.OrSubChildren).subscribe(
        myData => {

หรือเมื่อคุณกำหนดข้อมูลให้กับตัวแปรภายในเครื่องของคุณ

posts: Array<String>;    
this.posts = myData['anyChildren'];

(ไม่แน่ใจว่าตัวแปรนั้นจำเป็นต้องเป็น Array String หรือไม่ แต่นั่นคือสิ่งที่ฉันมีในตอนนี้มันอาจทำงานเป็นตัวแปรทั่วไปมากกว่า)

และหมายเหตุสุดท้ายไม่จำเป็นต้องใช้ไลบรารี JSON ที่สร้างขึ้น แต่คุณอาจพบว่าการโทรทั้ง 2 นี้มีประโยชน์สำหรับการแปลงจากวัตถุเป็นสตริงและในทางกลับกัน

        var stringifiedData = JSON.stringify(this.movies);                  
        console.log("**mResults in Stringify");
        console.log(stringifiedData);

        var mResults = JSON.parse(<string>stringifiedData);
        console.log("**mResults in a JSON");
        console.log(mResults);

ฉันหวังว่าการรวบรวมข้อมูลนี้จะช่วยใครบางคนได้


2
//Get solution for ng-repeat    
//Add variable and assign with Object.key

    export class TestComponent implements OnInit{
      objectKeys = Object.keys;
      obj: object = {
        "test": "value"
        "test1": "value1"
        }
    }
    //HTML
      <div *ngFor="let key of objectKeys(obj)">
        <div>
          <div class="content">{{key}}</div>
          <div class="content">{{obj[key]}}</div>
        </div>

1

ใน JavaScript สิ่งนี้จะแปลเป็นวัตถุที่มีข้อมูลอาจมีลักษณะเช่นนี้

อินเทอร์เฟซใน TypeScript เป็นการสร้างเวลาในการพัฒนา (เฉพาะสำหรับการใช้เครื่องมือ ... 0 ผลกระทบรันไทม์) คุณควรเขียน TypeScript เดียวกันกับ JavaScript ของคุณ


นั่นไม่เป็นความจริงเลย type script บังคับให้คุณเขียนโค้ดที่สะอาดขึ้น คลาสนามธรรมง่ายกว่ามาก ซึ่งคุณไม่มี C ++ คอมไพล์ไปยัง asm บางตัว - asm ยังไม่มีคลาสหรือแม้แต่ประเภทอย่างไรก็ตามคุณเขียน c ++ ที่แตกต่างกันตามด้วย ur asm code: P
YAMM

1

พจนานุกรมเป็นวัตถุไม่ใช่อาร์เรย์ ฉันเชื่อว่า ng-repeat ต้องใช้อาร์เรย์ใน Angular 2

ทางออกที่ง่ายที่สุดคือการสร้างไปป์ / ตัวกรองที่แปลงวัตถุเป็นอาร์เรย์ได้ทันที ที่กล่าวมาคุณอาจต้องการใช้อาร์เรย์ตามที่ @basarat กล่าว


1

หากคุณมีes6-shimหรือtsconfig.jsonเป้าหมายของes6คุณคุณสามารถใช้ ES6 Mapเพื่อสร้างได้

var myDict = new Map();
myDict.set('key1','value1');
myDict.set('key2','value2');

<div *ngFor="let keyVal of myDict.entries()">
    key:{{keyVal[0]}}, val:{{keyVal[1]}}
</div>

0

กำหนดMapValuesPipeและใช้PipeTransform :

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

@Pipe({name: 'mapValuesPipe'})
export class MapValuesPipe implements PipeTransform {
    transform(value: any, args?: any[]): Object[] {
        let mArray: 
        value.forEach((key, val) => {
            mArray.push({
                mKey: key,
                mValue: val
            });
        });

        return mArray;
    }
}

เพิ่มท่อของคุณในโมดูลท่อของคุณ นี่เป็นสิ่งสำคัญหากคุณต้องการใช้ท่อเดียวกันในส่วนประกอบมากกว่าหนึ่งชิ้น :

@NgModule({
  imports: [
    CommonModule
  ],
  exports: [
    ...
    MapValuesPipe
  ],
  declarations: [..., MapValuesPipe, ...]
})
export class PipesAggrModule {}

จากนั้นใช้ไปป์ใน html ของคุณด้วย*ngFor:

<tr *ngFor="let attribute of mMap | mapValuesPipe">

จำไว้ว่าคุณจะต้องประกาศ PipesModule ของคุณในส่วนประกอบที่คุณต้องการใช้ไปป์:

@NgModule({
  imports: [
    CommonModule,
    PipesAggrModule
  ],
...
}
export class MyModule {}

0

ดังนั้นฉันจะใช้ฟังก์ชันตัวช่วยของตัวเอง objLength (obj) ซึ่งส่งคืนแค่ Object (obj) .keys.length แต่เมื่อฉันเพิ่มลงในฟังก์ชัน template * ngIf IDE ของฉันแนะนำ objectKeys () ฉันลองแล้วและได้ผล ตามคำประกาศของมันดูเหมือนว่าจะมีให้โดย lib.es5.d.ts ดังนั้นคุณไปได้เลย!

นี่คือวิธีที่ฉันใช้งาน (ฉันมีออบเจ็กต์แบบกำหนดเองที่ใช้คีย์ที่สร้างจากฝั่งเซิร์ฟเวอร์เป็นดัชนีสำหรับไฟล์ที่ฉันอัปโหลด):

        <div *ngIf="fileList !== undefined && objectKeys(fileList).length > 0">
          <h6>Attached Files</h6>
          <table cellpadding="0" cellspacing="0">
            <tr *ngFor="let file of fileList | keyvalue">
              <td><a href="#">{{file.value['fileName']}}</a></td>
              <td class="actions">
                <a title="Delete File" (click)="deleteAFile(file.key);">
                </a>
              </td>
            </tr>
          </table>
        </div>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.