2016-10-31 7 views
9

In Angular 2 bei der Verwendung von ngFor wie würde ich den ursprünglichen Index für ein Objekt innerhalb eines Arrays erhalten, nachdem es durch ein Rohr passiert wurde?Angular 2 - ngFor Index nach einer Pipe

Zum Beispiel, wenn ich ein Array von Objekten wie folgt:

list = [{type:"A",id:111},{type:"A",id:222},{type:"B",id:333},{type:"A",id:444},{type:"B",id:555}]; 

Und mit dem folgenden Rohr:

@Pipe({ 
    name: 'appFilter', 
    pure: false 
}) 
export class AppFilterPipe implements PipeTransform { 
// Single Argument Filter 
    transform(values: any[], arg1: any, arg2: any): any { 
    return values.filter(value => value[arg1] === arg2); 
    } 
} 

ich eine ngFor wie folgt erstellen:

<div *ngFor= "let item of list|AppFilter:'type':'B'|let index=index;trackBy:trackByIndex;"> 
{{index}} - {{item.id}} 
<input [(ngModel)]="list[index]" placeholder="item"> 
</div> 

Das Problem hierbei ist, dass der von der ngFor zurückgegebene Index auf einem neuen Array basiert, das von AppFilter mit dem Index 0 und 1 zurückgegeben wird Dies bewirkt, dass das Eingabefeld auf den falschen Index verweist, dh es zeigt die Objekte des Typs A an, da es dem Index 0, 1 in der ursprünglichen Liste entspricht. Um Typ B zu bekommen, brauche ich wirklich den Index 2,4.

Schätzen Sie eine Arbeit zu diesem Thema. Auch meine trackByIndex in der Komponente zur Zeit wie folgt aussieht:

trackByIndex(index: number, obj: any): any { 
    return index; 
    } 
+0

Ich denke, es wäre am besten, um zu filtern Bevor Sie "List" zuweisen. –

Antwort

7

Sie auch reduce Methode ursprünglichen Index zu halten, verwenden können:

@Pipe({ 
    name: 'appFilter', 
    pure: false 
}) 
export class AppFilterPipe implements PipeTransform { 
    transform(values: any[], arg1: any, arg2: any): any { 
    return values.reduce((acc, value, index) => 
     value[arg1] === arg2 ? [...acc, { index, value }] : acc, []); 
    } 
} 

und dann in html

{{item.index}} - {{item.value.id}} 

Plunker Example

2

Wenn ich Sie richtig verstanden Sie Index der ursprünglichen Liste wollen, in diesem Fall, dass Sie diese gefilterte Objekt verwenden können, um Ursprung Index von der ursprünglichen Liste herausfinden.

und dann definieren Sie die geIndex-Methode in Ihrer Komponente, die den Index aus der ursprünglichen Liste zurückgeben kann, die nicht gefiltert wurde.

getIndex(item: Item) { 
    return this.list.indexOf(this.list.filter((i, index) => item.id == i.id)[0]) 
} 
+0

Dies ist einer meiner Ansätze am Anfang, aber ich denke, der Grund, den ursprünglichen Index beizubehalten, besteht darin, den Index nicht erneut zu berechnen, um etwas Speicher zu sparen. Wenn wir eine riesige Liste haben, wird das Finden des Index wieder zu teuer sein. – trungk18

+0

@ trungk18 ein anderer Weg wäre, dass Sie Karte einmal Ihre Liste mit Index zuordnen, so dass Sie Index von jedem Element in der Liste haben und Sie brauchen überhaupt keine Schleife mehr. –

+0

Ja, wahrscheinlich machen wir die Karte am Anfang und speichern den Index innerhalb des Objekts. – trungk18