Angular에서 개체 위에 반복
2에서 몇 작업을 과 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>
모든 경우 다음과 같은 오류가 발생합니다.Unexpected token
또는Cannot find 'iterableDiff' pipe supporting object
내가 여기서 뭘 놓쳤지요?이것은 더 이상 불가능합니까?(첫 번째 구문은 Angular 1.x에서 작동) 또는 개체를 반복하기 위한 구문이 다릅니까?
Angular 6.1.0+ 정답
내장된 파이프를 다음과 같이 사용합니다.
<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 파이프는 모든 템플릿에서 기본 제공되므로 모듈에 등록할 필요가 없습니다.
Javascript-Maps에서도 작동합니다.
ng1의 구문을 지원하지 않으려는 것 같습니다.
미슈코 헤베리(참고 자료)에 따르면:
지도에는 키 순서가 없으므로 반복을 예측할 수 없습니다.이것은 ng1에서 지원되었지만, 우리는 그것이 실수였다고 생각하고 NG2에서는 지원되지 않을 것입니다.
그 계획은 지도를 가지고 있는 것입니다.
<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
}
이 파이프를 사용해 보세요.
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>
: 는 이제 "Angular": "Angular": "json Object"를 통해 위한 합니다.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>
@obscur의 답변 외에도, 다음은 두 가지 모두에 액세스할 수 있는 방법의 예입니다.key
그리고.value
@보기.
파이프:
@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
}
생성된 결과는 다음과 같습니다.
: 다리오
이름:이름: 주
파일:
이름:이름:그레이조이
파일:
: 공
사이먼 하우섬의 훌륭한 답변에 더해서요.저는 새로운 타자기 기능 중 일부를 활용한 간결한 버전을 만들었습니다.저는 사이먼 하우섬의 버전이 근본적인 세부 사항을 설명하기 위해 의도적으로 장황하다는 것을 알고 있습니다.파이프가 잘못된 값을 위해 작동하도록 조기 체크도 추가했습니다.예를 들어, 지도가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] }));
}
}
다음은 다중 변환(키벌, 키, 값)을 지원하는 위 답변 중 일부에 대한 변형입니다.
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>
저도 비슷한 문제가 있었습니다. 객체와 지도를 위한 무언가를 만들었습니다.
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;
}
}
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>
//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>
다차원 객체를 사용하는 방법을 궁금해하는 사용자가 있다면 해결책은 다음과 같습니다.
다음과 같은 물체가 작동 중이라고 가정합니다.
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>
JSON 쿼리/api 호출에서 반환된 데이터를 분석하고 사용하려고 노력하면서 머리를 쥐어뜯고 있습니다.제가 어디서 잘못되고 있었는지 정확히 모르겠습니다. 며칠 동안 답을 빙빙 돌면서 다음과 같은 다양한 오류 코드를 쫓고 있는 것 같습니다.
"'iterableDiff' 파이프 지원 개체를 찾을 수 없습니다."
"일반 TYPE 어레이에는 하나의 인수가 필요합니다."
JSON 구문 분석 오류 및 기타 오류 확인
나는 내가 단지 잘못된 조합의 수정을 가졌을 뿐이라고 생각합니다.
그래서 여기에 gotchas와 찾아야 할 것들에 대한 요약이 있습니다.
먼저 api 호출의 결과를 확인하십시오. 결과는 객체, 배열 또는 객체의 배열 형태일 수 있습니다.
저는 그것에 너무 많이 들어가지는 않을 것입니다, OP의 원래 오류는 일반적으로 배열이 아닌 객체를 반복하려고 시도함으로써 발생한다고 말하면 충분합니다.
다음은 어레이와 객체의 변수를 보여주는 디버깅 결과 중 일부입니다.
따라서 일반적으로 JSON 결과를 반복하고 싶으므로 이 결과가 어레이 형태인지 확인해야 합니다.저는 수많은 예시들을 시도했고, 아마도 제가 알고 있는 것들 중 일부가 실제로 효과가 있을 것이라는 것을 알고 있었지만, 제가 사용한 접근법은 실제로 파이프를 구현하는 것이었고, 제가 사용한 코드는 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의 'ionic generate pipe' 명령을 사용하여 파이프 모듈.ts가 올바르게 생성되고 참조되는지 확인합니다.다음을 내 페이지에 추가해야 합니다.module.ts 페이지
import { PipesModule } from ‘…/…/pipes/pipes.module’;
(사용자 고유의 custom_proxy가 있는 경우 이 값이 변경되면 custommodule.custom.ts에 이 값을 추가해야 할 수도 마찬가지입니다.
만약 당신이 당신의 페이지를 만들기 위해 'ionic generate page' 명령을 사용했지만, 그 페이지를 당신의 메인 페이지로 사용하기로 결정했다면, app.message.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를 호출하면 하위 데이터(어레이 내의 개체 또는 배열)에 액세스할 수 있는 것처럼 보입니다. 두 가지 방법 중 하나가 작동하는 것처럼 보입니다.
상담 중이거나
this.http.get('https://SomeWebsiteWithAPI').map(res => res.json().anyChildren.OrSubChildren).subscribe(
myData => {
또는 데이터를 로컬 변수에 할당할 때
posts: Array<String>;
this.posts = myData['anyChildren'];
(해당 변수가 배열 문자열이어야 하는지는 확실하지 않지만, 지금은 그렇게 되어 있습니다.보다 일반적인 변수로 작동할 수 있습니다.)
그리고 마지막으로, 내장된 JSON 라이브러리를 사용할 필요는 없었지만, 이 두 가지 통화는 객체에서 문자열로 변환하거나 그 반대로 변환하는 데 유용할 수 있습니다.
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);
이 정보 편집이 누군가에게 도움이 되길 바랍니다.
사전이 배열이 아닌 개체입니다.ng-repeat은 Angular 2의 배열이 필요하다고 생각합니다.
가장 간단한 해결책은 객체를 즉시 배열로 변환하는 파이프/필터를 만드는 것입니다.그렇긴 하지만, 당신은 @basarat이 말한 것처럼 배열을 사용하기를 원할 것입니다.
가지고 계신다면,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>
JavaScript에서 이것은 데이터가 있는 개체로 변환됩니다.
TypeScript의 인터페이스는 개발 시간 구조입니다(단순히 툴링용... 런타임 영향 0).당신은 당신의 자바스크립트와 같은 타입스크립트를 작성해야 합니다.
「 」를 합니다.MapValuesPipe
파이프 변환을 구현합니다.
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">
파이프를 사용할 구성 요소에서 파이프 모듈을 선언해야 합니다.
@NgModule({
imports: [
CommonModule,
PipesAggrModule
],
...
}
export class MyModule {}
그래서 Object(obj)만 반환하는 나만의 도우미 함수 objLength(obj)를 구현하려고 했습니다.키, 길이그러나 템플릿 *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>
구조 지시어를 사용하여 객체를 루프하는 또 다른 방법이 있습니다.
저는 이 접근 방식이 일반적인 ngFor 루프와 가장 "느껴지기" 때문에 선호합니다. :-)
(예를 들어 이 경우 루프 내에서 액세스할 수 있는 Angular의 컨텍스트 변수를 i = 인덱스 | 짝수 | 홀수 | 첫 번째 | 마지막 | 카운트) 추가했습니다.
@Directive({
selector: '[ngForObj]'
})
export class NgForObjDirective implements OnChanges {
@Input() ngForObjOf: { [key: string]: any };
constructor(private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) { }
ngOnChanges(changes: SimpleChanges): void {
if (changes.ngForObjOf && changes.ngForObjOf.currentValue) {
// remove all views
this.viewContainerRef.clear();
// create a new view for each property
const propertyNames = Object.keys(changes.ngForObjOf.currentValue);
const count = propertyNames.length;
propertyNames.forEach((key: string, index: number) => {
const even = ((index % 2) === 0);
const odd = !even;
const first = (index === 0);
const last = index === (count - 1);
this.viewContainerRef.createEmbeddedView(this.templateRef, {
$implicit: changes.ngForObjOf.currentValue[key],
index,
even,
odd,
count,
first,
last
});
});
}
}
}
템플릿의 사용량:
<ng-container *ngForObj="let item of myObject; let i = index"> ... </ng-container>
또한 정수 값을 사용하여 루프를 수행하려면 다음 지시문을 사용할 수 있습니다.
@Directive({
selector: '[ngForInt]'
})
export class NgForToDirective implements OnChanges {
@Input() ngForIntTo: number;
constructor(private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.ngForIntTo && changes.ngForIntTo.currentValue) {
// remove all views
this.viewContainerRef.clear();
let currentValue = parseInt(changes.ngForIntTo.currentValue);
for (let index = 0; index < currentValue; index++) {
this.viewContainerRef.createEmbeddedView(this.templateRef, {
$implicit: index,
index
});
}
}
}
}
템플릿의 사용량(예: 0 ~ 14(= 15회 반복):
<ng-container *ngForInt="let x to 15"> ... </ng-container>
언급URL : https://stackoverflow.com/questions/31490713/iterate-over-object-in-angular
'source' 카테고리의 다른 글
람다 식은 대리자 형식이 아니므로 'string' 형식으로 변환할 수 없습니다. (0) | 2023.05.11 |
---|---|
이클립스에서는 다른 안드로이드 프로젝트에서 안드로이드 라이브러리 프로젝트를 참조할 수 없습니다. (0) | 2023.05.06 |
Git 및 일부 Git diff에서 커밋되지 않은 변화를 자세히 보여주는 방법 (0) | 2023.05.06 |
UIButton 제목 색상을 변경하려면 어떻게 해야 합니까? (0) | 2023.05.06 |
App_Code에 있는 클래스에 액세스할 수 없습니다. (0) | 2023.05.06 |