繁体   English   中英

如何在 Angular 中使用 ngFor 遍历对象属性

[英]How to loop over object properties with ngFor in Angular

这篇文章是关于我在工作中发现的一个有趣的问题。

如果你还不知道。 我说的是 Angular 2+

问题

所以你想显示一个列表的标记,这个列表的值来自后端,出于某种原因,你收到的不是一个很好的旧对象数组,而是这样的。

    { 
  "car" : 
    { 
       "color" : "red",
       "model" : "2013"
    },
   "motorcycle": 
    { 
       "color" : "red",
       "model" : "2016"
    },
   "bicycle": 
    { 
       "color" : "red",
       "model" : "2011"
    }
}

然后你尝试使用 *ngFor 但出现了一条错误消息:

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

您可能会在后端修复它,以便获得一组对象,但并不是没有人有时间这样做。 别担心,孩子,我有我们。

在 Angular 6.1 中引入了 KeyValuePipe,它允许您迭代对象属性:

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

文档: https ://angular.io/api/common/KeyValuePipe

我不知道这是否安全,但对于这些简单的情况,我不喜欢管道解决方案,所以我通常使用:

<div *ngFor="let k of objectKeys(yourObject)">
    {{yourObject[k].color}}
</div>

在控制器中:

objectKeys(obj) {
    return Object.keys(obj);
}

这是一个非常常见的情况,我不明白为什么在 Angular.js 1.x 中没有这样的标准实现

更好的解决方案是使用这样的管道:

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

/**
 * Convert Object to array of keys.
 */
@Pipe({
  name: 'appProperties'
})
export class PropertiesPipe implements PipeTransform {

  transform(value: {}): string[] {

    if (!value) {
      return [];
    }

    return Object.keys(value);
  }
}

然后在您的模板中:

<div *ngFor="let property of response | appProperties">
    <div *ngFor="let item of response[property]">
         {{item.something}}
    </div>
</div>
    <div *ngFor="let item of donation_list | keyvalue">
        <div class="donation-box">
             <Label class="donation-label">Date : {{item.value.PaymentDate}}</Label>
             <Label class="donation-label">Time : {{item.value.PaymentTime}}</Label>

        </div>
   </div>

如果对象内部有更多属性,则可以这样使用。

使用 Object.values 从您的对象中获取常规数组。 Object.keys 似乎是很多不必要的工作。

参考: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

解决方案

在一个完美的世界中,你会得到一系列对象,因为世界并不总是完美的。 您想要做的是将所有这些对象存储在一个数组中。 这是一个使用普通旧 JavaScript 的过度简化的解决方案。

步骤 1.获取所有对象键。 使用 Object.keys。 此方法返回给定对象自己的可枚举属性的数组。

步骤 2.创建一个空数组。 这是所有属性都将存在的地方,因为您的新 ngFor 循环将指向该数组,我们必须全部捕获它们。

步骤 3.迭代 throw all 键,并将每个键推入您创建的数组中。

这是代码中的样子。

// Evil response in a variable. Here are all my vehicles.
let evilResponse = { 
  "car" : 
    { 
       "color" : "red",
       "model" : "2013"
    },
   "motorcycle": 
    { 
       "color" : "red",
       "model" : "2016"
    },
   "bicycle": 
    { 
       "color" : "red",
       "model" : "2011"
    }
}
// Step 1. Get all the object keys.
let evilResponseProps = Object.keys(evilResponse);
// Step 2. Create an empty array.
let goodResponse = [];
// Step 3. Iterate throw all keys.
for (prop of evilResponseProps) { 
    goodResponse.push(evilResponseProps[prop]);
}

然后,您可以将 goodResponse 分配给您首先尝试迭代的类属性。

这就是所有人。

将您的数组声明为任何,然后分配您的对象

data=[] as any;
myObj={};

data=myObj;

现在循环遍历数据数组

<tr *ngFor="let item of data">
<td>{{item.property}}</td>
</tr>

有2种方式:

  1. 如果您的对象项目没有密钥

    { name: 'John', age: 18,... } <div *ngFor="let item of myObj | keyvalue"> Key: <strong>{{item.key}}</strong> and Value: <span>{{item.value}}</span> </div>
  2. 如果您的对象项有键

    管道

    import { Pipe, PipeTransform } from "@angular/core"; type Args = "keyvalue" | "value" | "key"; @Pipe({ name: "pipeMapToIterable", pure: false }) export class MapToIterablePipe implements PipeTransform { transform(obj: {}, arg: Args = "keyvalue") { return arg === "keyvalue"? 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; } }

    HTML

     { John: { name: 'John', age: 18 }, Bob: { name: 'Bob', age: 25}, Marry: { name: 'Marry', age: 22} } <:-- default --> <div *ngFor="let item of myObj | pipeMapToIterable"> Key. <strong>{{item:key}}</strong> and Value. <span>{{item:value}</span> </div> <:-- keyvalue --> <div *ngFor="let item of myObj | pipeMapToIterable. 'keyvalue'"> Key: <strong>{{item.key}}</strong> and Value: <span>{{item:value}</span> </div> <.-- value --> <div *ngFor="let item of myObj | pipeMapToIterable: 'value'"> Key. <strong>{{item:key}}</strong> and Value: <span>{{item.value}</span> </div> <:-- key --> <div *ngFor="let item of myObj | pipeMapToIterable. 'key'"> Key: <strong>{{item.key}}</strong> and Value: <span>{{item.value}</span> </div>

你可以试试这个:

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

欲了解更多信息,请访问: https ://angular.io/api/common/KeyValuePipe

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM