typescript - angular keyvalue pipe sortere egenskaper/iterere i rekkefølge
Når du bruker Angular keyvalue-pipen for å iterere over et objekts egenskaper som følger:
<div *ngFor="let item of object | keyvalue">
{{item.key}}:{{item.value}}
</div>
Jeg har opplevd et problem der egenskapene ikke ble iterert i den forventede rekkefølgen. Og denne kommentaren antyder at jeg ikke er den eneste som har opplevd dette problemet:
Hvordan gå gjennom objektets egenskaper med ngFor i Angular
Kan noen gi råd om hva som bestemmer rekkefølgen på iterasjon når man bruker keyvalue-pipen, og hvordan man kan tvinge en spesifikk iterasjonsrekkefølge? Min ideelle iterasjonsrekkefølge er den rekkefølgen egenskapene ble lagt til.
Takk
Svar #1
I følge Angular-dokumentasjonen sorterer keyvalue-pipe elementene etter key-rekkefølge som standard. Du kan gi en sammenligningsfunksjon for å endre den rekkefølgen, og sortere elementene etter key, etter value, eller etter rekkefølgen til egenskapene i objektet.
De følgende sammenligningsfunksjonene sorterer elementene i ulike rekkefølger:
// Preserve original property order
originalOrder = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
return 0;
}
// Order by ascending property value
valueAscOrder = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
return a.value.localeCompare(b.value);
}
// Order by descending property key
keyDescOrder = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
return a.key > b.key ? -1 : (b.key > a.key ? 1 : 0);
}
når den brukes på keyvalue-pipe:
<div *ngFor="let item of object | keyvalue: originalOrder">
{{item.key}} : {{item.value}}
</div>
<div *ngFor="let item of object | keyvalue: valueAscOrder">
{{item.key}} : {{item.value}}
</div>
<div *ngFor="let item of object | keyvalue: keyDescOrder">
{{item.key}} : {{item.value}}
</div>
Se denne stackblitz for en demo.
Å levere en konstant eller null i stedet for en gyldig sammenligningsfunksjon bevarer rekkefølgen på objektets egenskaper, slik originalOrder gjør, men det forårsaker en unntak (se dette stackblitz-eksemplet):
<!-- The following syntaxes preserve the original property order -->
<div *ngFor="let item of object | keyvalue: 0">
<div *ngFor="let item of object | keyvalue: 374">
<div *ngFor="let item of object | keyvalue: null">
<!-- but they cause an exception (visible in the console) -->
ERROR TypeError: The comparison function must be either a function or undefined
Dessuten vil bruk av den syntaksen to ganger i malen ikke vise elementene i det hele tatt. Derfor vil jeg ikke anbefale det. Vennligst merk at det å oppgi undefined som sammenligningsfunksjon ikke forårsaker noen unntak, men endrer ikke standardoppførselen: elementene sorteres etter key-verdien.
Svar #2
<div *ngFor="let item of object | keyvalue: 0">
{{item.key}} : {{item.value}}
</div>
skriv direkte, og du vil få dataene i samme rekkefølge som de er i json
keyvalue: 0
Svar #3
Ja, som standard sorterer nøkkel-verdiparene dataene i stigende rekkefølge.
For å holde det usortert, endre som:
keyvalue: 0
Endelig kode:
<div *ngFor="let item of object | keyvalue:0">
{{item.key}}:{{item.value}}
</div>
Men for Angular 7 eller nyere, må du sette en tom funksjon for å holde dataene usorterte.
<div *ngFor="let item of object | keyvalue: unsorted">
{{item.key}}:{{item.value}}
</div>
I din .ts-fil, bare legg denne tomme funksjonen.
unsorted() { }
Håper det er nyttig.
Svar #4
For å beholde objektsrekkefølgen kan du bruke
keepOrder = (a, b) => {
return a;
}
La oss si at du har
wbs = {
"z": 123,
"y": 456,
"x": 789,
"w": 0#*
}
Hvis du bruker keyvalue får du alfabetisk rekkefølge etter nøkkel
w 0#*
x 789
y 456
z 123
ved å bruke :keepOrder beholder du objektrekkefølgen
<ion-item *ngFor="let w of wbs | keyvalue: keepOrder">
<ion-label>{{ w.key }}</ion-label>
<ion-label>{{ w.value }}</ion-label>
</ion-item>
Svar #5
Dette er det samme som det aksepterte svaret, men det har et mer komplekst objekt, så det kan hjelpe noen med hvordan man sorterer etter tilpasset indeksfelt og bruker keyval-pipe.
I Angular-komponenten:
myObject = {
"key1": { val:"whateverVal1", code:"whateverCode1", index: 1},
"key2": { val:"whateverVal2", code:"whateverCode2", index: 0},
"key3": { val:"whateverVal3", code:"whateverCode3", index: 2}
}
Sorteringsfunksjon i komponent:
indexOrderAsc = (akv: KeyValue<string, any>, bkv: KeyValue<string, any>): number => {
const a = akv.value.index;
const b = bkv.value.index;
return a > b ? 1 : (b > a ? -1 : 0);
};
i mal:
<div *ngFor="let x of myObject | keyvalue:indexOrderAsc">
...
</div>
