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>

Relaterte artikler