web-dev-qa-db-ja.com

Angular2のオブジェクトの配列を並べ替える

Angular2のオブジェクトの配列のソートに問題があります。

オブジェクトは次のようになります。

[
  {
    "name": "t10",
    "ts": 1476778297100,
    "value": "32.339264",
    "xid": "DP_049908"
  },
  {
    "name": "t17",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_693259"
  },
  {
    "name": "t16",
    "ts": 1476778341100,
    "value": "true",
    "xid": "DP_891890"
  }
]

そして、values変数内に格納されています。

必要なのは、*ngForループをnameプロパティでソートすることだけです。

<table *ngIf="values.length">
    <tr *ngFor="let elem of values">
      <td>{{ elem.name }}</td>
      <td>{{ elem.ts }}</td>
      <td>{{ elem.value }}</td>
    </tr>
</table>

パイプでそれをしようとしましたが、惨めに失敗しました。任意の助けに感謝します。

プランカーリンクhttps://plnkr.co/edit/e9laTBnqJKb8VzhHEBmn?p=preview

編集

私のパイプ:

import {Component, Inject, OnInit, Pipe, PipeTransform} from '@angular/core';

@Component({
  selector: 'watchlist',
  templateUrl: './watchlist.component.html',
  styleUrls: ['./watchlist.component.css'],
  pipes: [ ArraySortPipe ]
})
@Pipe({
  name: "sort"
})

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<string>, args: string): Array<string> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

そして、pipeの名前をhtmlファイルに入れるだけです:

<tr *ngFor="let elem of values | sort">
23
user7209780

パイプを使用してこの問題を解決できますが、特定のプロジェクトでパイプの再利用が役立つかどうかを自問する必要があります。将来、他の配列または他のコンポーネントの「名前」キーでオブジェクトをソートする必要が頻繁にありますか?このデータは十分に頻繁に変化し、コンポーネント内で単純にソートするのが困難になるような方法で変化しますか?ビューまたは入力の変更時にソートされた配列が必要ですか?

コンポーネントのコンストラクターで配列がソートされる編集済みのプランカーを作成しましたが、必要に応じて再利用するためにこの機能を独自のメソッド(sortValuesArrayなど)に移動できない理由はありません。

constructor() {
  this.values.sort((a, b) => {
    if (a.name < b.name) return -1;
    else if (a.name > b.name) return 1;
    else return 0;
  });
}

編集されたプランカー

22
peterhuettl

これを試して

Aからアルファベットの最後まで並べ替えます。

this.suppliers.sort((a,b)=>a.SupplierName.localeCompare(b.SupplierName));

Z => A(逆順)

this.suppliers.sort((a,b)=>b.SupplierName.localeCompare(a.SupplierName));
17
suphi

パイプは文字列を想定していますが、オブジェクトを取得するため、それを適応させる必要があります。

export class ArraySortPipe implements PipeTransform {
  transform(array: Array<any>): Array<string> {
    array.sort((a: any, b: any) => {
      if (a.name < b.name) {
        return -1;
      } else if (a.name > b.name) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}
13
Meir

Angularは、angularJsのように、ソートとフィルタリングにパイプを使用しないことを引き続き推奨します。

アプリケーションの速度が低下し、パフォーマンスの問題が発生します。コンポーネントをテンプレートに渡す前に、コンポーネントでソートを提供する方がはるかに優れています。

理由は https://angular.io/guide/pipes#no-filter-pipe で説明されています

Nice構造化コンポーネントレイアウトを使用する場合、setterでも実行できます。

 @Input()
  set users(users: Array<User>) {
    this.usersResult = (users || []).sort((a: User, b: User) => a.name < b.name ? -1 : 1)
  }
8
Bo Vandersteene

これは、そのようなユースケースに適応可能です。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sortBy'
})
export class SortByPipe implements PipeTransform {
  transform(arr: Array<any>, prop: any, reverse: boolean = false): any {
    if (arr === undefined) return
    const m = reverse ? -1 : 1
    return arr.sort((a: any, b: any): number => {
      const x = a[prop]
      const y = b[prop]
      return (x === y) ? 0 : (x < y) ? -1*m : 1*m
    })
  }
}

使用法:-
<div *ngFor="let item of list | sortBy: 'isDir': true">

UPDATE
Refer Bo's パイプでのフィルタリングとソートはお勧めできません。

3
Vikas Gautam