угловые свойства сортировки соляных ключей/итерация по порядку

При использовании канала Angular keyvalue для перебора свойств объекта следующим образом:

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

Я столкнулся с проблемой, когда свойства не повторялись в ожидаемом порядке. И этот комментарий говорит о том, что я не единственный, кто испытал эту проблему:

Как перебрать свойства объекта с помощью ngFor в Angular

Может кто-нибудь посоветовать, что определяет порядок итерации при использовании канала значения ключа, пожалуйста, и как заставить определенный порядок итерации? Мой идеальный порядок итераций - это порядок добавления свойств.

Спасибо

Ответ 1

Согласно документации Angular, канал keyvalue сортирует элементы по порядку key по умолчанию. Вы можете предоставить функцию сравнения для изменения порядка сортировки, но она учитывает только свойства key и value, а не порядок ввода.

Например, следующие функции сравнения сортируют элементы в порядке возрастания значения и в порядке обратного ключа соответственно:

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>

Смотрите этот стек для демонстрации.

Ответ 2

Это то же самое, что и принятый ответ, но у него более сложный объект, поэтому он может помочь кому-то Как сортировать по пользовательскому полю индекса и использовать keyval pipe.

В угловом компоненте:

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#*
}

Если вы используете значение ключа, вы получите алфавитный порядок по ключу

w 0#*
x 789
y 456
z 123

apply: keepOrder вы сохраняете порядок объектов

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

Ответ 4

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

напишите прямо, и вы получите данные в том же порядке, что и в json

keyvalue: 0

Ответ 5

Да, свойства 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>