programing

ngFor in Angular를 사용하여 개체 속성을 루프오버하는 방법

cafebook 2023. 8. 16. 22:38
반응형

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를 사용하여 개체에서 정규 배열을 가져옵니다.물건.열쇠는 많은 불필요한 일처럼 보입니다.

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

두 가지 방법이 있습니다.

  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>
    

해결책

완벽한 세상에서, 여러분은 다양한 물건들을 얻게 될 것입니다. 세상이 항상 완벽한 것은 아니기 때문입니다.여러분이 원하는 것은 배열 안에 모든 개체를 저장하는 것입니다.다음은 일반적인 오래된 자바스크립트에서 지나치게 단순화된 솔루션입니다.

1단계. 모든 객체 키를 가져옵니다.Object.key를 사용합니다.이 메서드는 지정된 개체의 고유한 열거 가능한 속성 배열을 반환합니다.

2단계. 빈 배열을 만듭니다.여기는 모든 속성이 살 곳입니다. 새로운 ngFor 루프가 이 배열을 가리킬 것이기 때문에, 우리는 그것들을 모두 잡아야 합니다.

3단계. 모든 키를 반복해서 던지고 각 키를 작성한 배열로 밀어 넣습니다.

이것이 코드에서 어떻게 보이는지입니다.

// 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를 할당할 수 있습니다.

이상입니다.

사용해 볼 수 있습니다.

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

자세한 내용은 https://angular.io/api/common/KeyValuePipe 를 참조하십시오.

배열을 임의로 선언한 다음 개체 할당

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

data=myObj;

이제 데이터 어레이를 순환합니다.

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

언급URL : https://stackoverflow.com/questions/45819123/how-to-loop-over-object-properties-with-ngfor-in-angular

반응형