angular keyvalue pipe排序属性/按顺序迭代

问题描述 投票:6回答:3

使用Angular keyvalue管道迭代对象的属性时,如下所示:

<div *ngFor="let item of object | keyvalue">
  {{item.key}}:{{item.value}}
</div>

我遇到了一个问题,即属性没有按预期的顺序迭代。这条评论表明我并不是唯一一个遇到这个问题的人:

How to loop over object properties with ngFor in Angular

有人可以建议在使用keyvalue管道时决定迭代顺序的内容以及如何强制执行特定的迭代顺序吗?我理想的迭代顺序是添加属性的顺序。

谢谢

angular angular-pipe
3个回答
27
投票

根据Angular documentationkeyvalue管道默认按key顺序对项目进行排序。您可以提供比较器函数来更改排序顺序,但它只考虑keyvalue属性,而不是输入顺序。

例如,以下比较器函数分别通过增加值顺序和反向键顺序对项目进行排序:

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

当应用于keyvalue管道时:

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

有关演示,请参阅this stackblitz


5
投票

这与接受的答案相同,但它有更复杂的对象,所以它可以帮助有人如何按自定义索引字段排序和使用keyval管道。

在角度分量中:

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

组件中的排序功能:

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

在模板中:

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

3
投票

要保持对象顺序,您可以使用

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

让我们说你有

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

如果您使用keyvalue,则按键按字母顺序排序

w 0#*
x 789
y 456
z 123

申请:keepOrder你保持对象顺序

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

1
投票

是的,Object属性是随机迭代的,因为它不会在内存中存储为array。但是,您可以按属性排序。

如果要按插入位置进行迭代,则需要创建一个额外的属性,如index,并设置timestamp并按index排序。

下面是可用于控制排序和迭代的管道

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

用法

<div *ngFor='#item in object | values:"keyName":true'>...</div>
© www.soinside.com 2019 - 2024. All rights reserved.