angular keyvalue pipe sort properties / iterate in order

帅比萌擦擦* 提交于 2019-11-30 12:17:40
ConnorsFan

According to the Angular documentation, the keyvalue pipe sorts the items by key order by default. You can provide a comparer function to change the sort order, but it only considers the key and value properties, not the entry order.

For example, the following comparer functions sort the items by increasing value order, and by reverse key order, respectively:

valueAscOrder = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
  return a.value.localeCompare(b.value);
}

keyDescOrder = (a: KeyValue<number,string>, b: KeyValue<number,string>): number => {
  return a.key > b.key ? -1 : (b.key > a.key ? 1 : 0);
}

when applied to the keyvalue pipe:

<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>

See this stackblitz for a demo.

This is same as accepted answer, but it has more complex object so It can help somebody How to sort by custom index field and using keyval pipe.

In angular component:

myObject = {
    "key1": { val:"whateverVal1", code:"whateverCode1", index: 1},
    "key2": { val:"whateverVal2", code:"whateverCode2", index: 0},
    "key3": { val:"whateverVal3", code:"whateverCode3", index: 2}
}

Sorting function in component:

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);
    };

in template:

<div *ngFor="let x of myObject | keyvalue:indexOrderAsc">
    ...
</div>

To keep the object order you can use

keepOrder = (a, b) => {
    return a;
}

Let's say you have

wbs = {
"z": 123,
"y": 456,
"x": 789,
"w": 0#*
}

If you use keyvalue you get alphabetical order by key

w 0#*
x 789
y 456
z 123

applying :keepOrder you keep object order

<ion-item *ngFor="let w of wbs | keyvalue: keepOrder">
    <ion-label>{{ w.key }}</ion-label>
    <ion-label>{{ w.value }}</ion-label>
</ion-item>
Sunil Singh

Yes, Object properties iterates randomly since it doesn't get stored as array in memory. However you can sort by properties.

If you want to iterate by insertion position, you need to create one extra property like index and set the timestamp and sort by index.

Below is the pipe you can use to control the sorting and iteration

Pipe

import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({name: 'values'})
export class ValuesPipe implements PipeTransform {
    transform(value: any, args?: any[]): Object[] {
        let keyArr: any[] = Object.keys(value),
            dataArr = [],
            keyName = args[0];

        keyArr.forEach((key: any) => {
            value[key][keyName] = key;
            dataArr.push(value[key])
        });

        if(args[1]) {
            dataArr.sort((a: Object, b: Object): number => {
                return a[keyName] > b[keyName] ? 1 : -1;
            });
        }

        return dataArr;
    }
}

Usage

<div *ngFor='#item in object | values:"keyName":true'>...</div>
<div *ngFor="let item of object | keyvalue: 0">
  {{item.key}} : {{item.value}}
</div>

directly write and you will get the data in sameorder as it is in the json

keyvalue: 0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!