web-dev-qa-db-ja.com

Angular Material 2 DataTableネストされたオブジェクトを使用した並べ替え

ソートヘッダーを持つ通常のAngular Material 2 DataTableがあります。すべての並べ替えは、ヘッダーが正常に機能します。値としてオブジェクトを持つものを除きます。これらはまったくソートされません。

例えば:

 <!-- Project Column - This should sort!-->
    <ng-container matColumnDef="project.name">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Project Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.project.name}} </mat-cell>
    </ng-container>

element.project.nameに注意してください

DisplayColumnの構成は次のとおりです。

 displayedColumns = ['project.name', 'position', 'name', 'test', 'symbol'];

'project.name''project'に変更しても機能しません。また、"project['name']"

私は何が欠けていますか?これも可能ですか?

Stackblitzは次のとおりです。 Angular Material2 DataTable sort objects

編集:回答ありがとうございます。動的データを使用して既に動作しています。したがって、新しいネストされたプロパティごとにswitchステートメントを追加する必要はありません。

私のソリューションは次のとおりです(MatTableDataSourceを拡張する新しいDataSourceを作成する必要はありません)

export class NestedObjectsDataSource extends MatTableDataSource<MyObjectType> {

  sortingDataAccessor: ((data: WorkingHours, sortHeaderId: string) => string | number) =
    (data: WorkingHours, sortHeaderId: string): string | number => {
      let value = null;
      if (sortHeaderId.indexOf('.') !== -1) {
        const ids = sortHeaderId.split('.');
        value = data[ids[0]][ids[1]];
      } else {
        value = data[sortHeaderId];
      }
      return _isNumberValue(value) ? Number(value) : value;
    }

  constructor() {
    super();
  }
}
46
Lados

これに関するドキュメントを見つけることは困難でしたが、sortingDataAccessorとswitchステートメントを使用することで可能です。例えば:

@ViewChild(MatSort) sort: MatSort;

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);
  this.dataSource.sortingDataAccessor = (item, property) => {
    switch(property) {
      case 'project.name': return item.project.name;
      default: return item[property];
    }
  };
  this.dataSource.sort = sort;
}
91
Steve Sanders

コンポーネントから関数を作成して、オブジェクトからプロパティを深く取得できます。次に、dataSource.sortingDataAccessorで以下のように使用します

getProperty = (obj, path) => (
  path.split('.').reduce((o, p) => o && o[p], obj)
)

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);
  this.dataSource.sortingDataAccessor = (obj, property) => this.getProperty(obj, property);
  this.dataSource.sort = sort;
}

columnDefs = [
  {name: 'project.name', title: 'Project Name'},
  {name: 'position', title: 'Position'},
  {name: 'name', title: 'Name'},
  {name: 'test', title: 'Test'},
  {name: 'symbol', title: 'Symbol'}
];

そして、html

<ng-container *ngFor="let col of columnDefs" [matColumnDef]="col.name">
      <mat-header-cell *matHeaderCellDef>{{ col.title }}</mat-header-cell>
      <mat-cell *matCellDef="let row">
        {{ getProperty(row, col.name) }}
      </mat-cell>
  </ng-container>
19
Hieu Nguyen

フィールドにドット表記を使用している限り、与えられた答えは短くすることもでき、スイッチは必要ありません。

ngOnInit() {
  this.dataSource = new MatTableDataSource(yourData);

  this.dataSource.sortingDataAccessor = (item, property) => {
     if (property.includes('.')) return property.split('.').reduce((o,i)=>o[i], item)
     return item[property];
  };

  this.dataSource.sort = sort;
}
6
Erik Schaareman

mat-sort-headerまたはmatColumnDefでdot.seperated.pathを使用できるようにする汎用メソッドを使用します。パスで指定されたプロパティが見つからない場合、これは暗黙的にundefinedを返すことに失敗します。

function pathDataAccessor(item: any, path: string): any {
  return path.split('.')
    .reduce((accumulator: any, key: string) => {
      return accumulator ? accumulator[key] : undefined;
    }, item);
}

データアクセサを設定するだけです

this.dataSource.sortingDataAccessor = pathDataAccessor;
3
Toby Harris

複数のネストされたオブジェクトレベルにカスタマイズしました。

this.dataSource.sortingDataAccessor =
  (data: any, sortHeaderId: string): string | number => {
    let value = null;
    if (sortHeaderId.includes('.')) {
      const ids = sortHeaderId.split('.');
      value = data;
      ids.forEach(function (x) {
        value = value? value[x]: null;
      });
    } else {
      value = data[sortHeaderId];
    }
    return _isNumberValue(value) ? Number(value) : value;
  };
1
E.Sarawut

私は同じ問題を抱えていました。いくつかのエラーがあった最初の命題をテストすることで、「スイッチ(プロパティ)」を追加することで修正できました。

this.dataSource.sortingDataAccessor =(item, property) => {
    switch (property) {
    case 'project.name': return item.project.name;

    default: return item[property];
    }
  };
0
kawthar

Element ['project.name']でソートしようとしています。明らかに要素にはそのようなプロパティはありません。

MatTableDatasourceを拡張し、ネストされたオブジェクトプロパティによる並べ替えをサポートするカスタムデータソースを簡単に作成できるはずです。 material.angular.ioのドキュメントで、カスタムソースの使用に関する例を確認してください。

0
funkizer