web-dev-qa-db-ja.com

Angular並べ替え、フィルター、ページネーションを実装する2つのマテリアル

Md-tableを使用して、並べ替え、フィルター、ページ分割を実装しようとしています。これが私のコードです:

connect(): Observable<Patient[]> {
const displayPatientDataChanges = [
  this._patientDatabase.dataChange,
  this._filterPatientChange,
  this._paginator.page,
  this._sort.mdSortChange,
];

return Observable.merge(...displayPatientDataChanges).map(() => {
  const startIndex = this._paginator.pageIndex * this._paginator.pageSize;

  let displayData = this._patientDatabase.data.slice().filter((item: Patient) => {
    let searchStr = (item.firstname + ' ' + item.lastname).toLowerCase();
    return searchStr.indexOf(this.filter.toLowerCase()) != -1;
  });

これらの両方の値を返したいのですが、フィルターとページネーションが機能しないソート関数のみが返されます。

  return displayData.splice(startIndex, this._paginator.pageSize),this.getSortedData();


});

}

 disconnect() { }

getSortedData(): Patient[] {
const data = this._patientDatabase.data.slice();
if (!this._sort.active || this._sort.direction == '') { return data; }

return data.sort((a, b) => {
  let propertyA: number|string|Date = '';
  let propertyB: number|string|Date = '';

  switch (this._sort.active) {
    case 'id': [propertyA, propertyB] = [a.id, b.id]; break;
    case 'firstname': [propertyA, propertyB] = [a.firstname, b.firstname]; break;
    case 'lastname': [propertyA, propertyB] = [a.lastname, b.lastname]; break;
    case 'dateOfBirth': [propertyA, propertyB] = [a.dateOfBirth, b.dateOfBirth]; break;
    case 'sex': [propertyA, propertyB]= [a.sex, b.sex]; break;
    case 'dateAdded': [propertyA, propertyB] = [a.dateAdded, b.dateAdded]; break;
  }

  let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
  let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

  return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'asc' ? 1 : 1);
});
 }

並べ替え、フィルター、ページネーションを機能させるにはどうすればよいですか?

5
user6003897

2018年1月29日編集:材料データテーブルに関する記事が作成され、表示できます here 、それ多くの人がこの投稿にアクセスしているので、サーバーのページネーション、フィルタリング、並べ替えが含まれており、おそらく以下のコードよりも最新です。これが本当に必要であると思います。

編集:plunkrの例は動作しなくなったため、stackblitzに最新のマテリアルリリース(この編集時点ではベータ12)で再実装しました。注:if古いバージョンの素材を使用している場合は、matプレフィックスをmdに戻す必要があります。

こちらが更新されたバージョンです

この plunkrの例 (動作しなくなりました。動作しているバージョンについては上記のリンクを参照してください)は、探しているすべての実装を含む表を表示します。

依存関係注入でどのように実装されているかを確認できます。

_    const displayDataChanges = [
  this._exampleDatabase.dataChange,
  this._sort.mdSortChange, 
  this._filterChange,
  this._paginator.page,
];
_

Observable.merge(...displayDataChanges).mapはデータをフィルタリングし、sortData()メソッドはデータをソートし、ページネーションはフィルタリングされたデータの長さに応じてページ数を生成します。

18
Lakston

これは、ページ分割と並べ替えの用途です。

import { Component, OnInit } from '@angular/core';
import { ViewChild, Output, EventEmitter } from '@angular/core';
import { DataSource } from '@angular/cdk';
import { MdPaginator, MdSort } from '@angular/material';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import { SharedService } from "app/services/shared.service";

@Component({
  selector: 'app-rtable',
  styleUrls: ['./rtable.component.css'],
  templateUrl: './rtable.component.html',
})
export class RtableComponent {
  displayedColumns = ['userId', 'userName', 'progress', 'color', 'url'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ExampleDataSource | null;

  @ViewChild(MdPaginator) paginator: MdPaginator;
  @ViewChild(MdSort) sort: MdSort;
  @Output()
  playAudioPlayer: EventEmitter<string> = new EventEmitter();

  constructor(private _sharedService: SharedService) { }

  ngOnInit() {
 
  }
}

const COLORS = ['maroon', 'red', 'orange', 'yellow', 'olive', 'green', 'purple',
  'Fuchsia', 'Lime', 'teal', 'aqua', 'blue', 'navy', 'black', 'gray'];
const NAMES = ['Maia', 'Asher', 'Olivia', 'Atticus', 'Amelia', 'Jack',
  'Charlotte', 'Theodore', 'Isla', 'Oliver', 'Isabella', 'Jasper',
  'Cora', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];
const URLS = ['http://localhost/ragnar1.mp3', 'http://localhost/ragnar1.mp3',
  'http://localhost/ragnar1.mp3', 'http://localhost/ragnar1.mp3',
  'http://localhost/ragnar2.mp3', 'http://localhost/ragnar2.mp3',
  'http://localhost/ragnar3.mp3', 'http://localhost/ragnar3.mp3',
  'http://localhost/ragnar1.mp3', 'http://localhost/ragnar1.mp3',
  'http://localhost/ragnar2.mp3', 'http://localhost/ragnar2.mp3',
  'http://localhost/ragnar3.mp3', 'http://localhost/ragnar3.mp3',
  'http://localhost/ragnar1.mp3', 'http://localhost/ragnar1.mp3',
  'http://localhost/ragnar2.mp3', 'http://localhost/ragnar2.mp3',
  'http://localhost/ragnar3.mp3'];

export interface UserData {
  id: string;
  name: string;
  progress: string;
  color: string;
  url: string;
}
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  get data(): UserData[] { return this.dataChange.value; }

  constructor() {
    // Fill up the database with 100 users.
    for (let i = 0; i < 100; i++) { this.addUser(); }
  }

  /** Adds a new user to the database. */
  addUser() {
    const copiedData = this.data.slice();
    copiedData.Push(this.createNewUser());
    this.dataChange.next(copiedData);
  }

  /** Builds and returns a new User. */
  private createNewUser() {
    const name =
      NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
      NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';

    return {
      id: (this.data.length + 1).toString(),
      name: name,
      progress: Math.round(Math.random() * 100).toString(),
      color: COLORS[Math.round(Math.random() * (COLORS.length - 1))],
      url: URLS[Math.round(Math.random() * (URLS.length - 1))]
    };
  }
}

export class ExampleDataSource extends DataSource<any> {
  constructor(private _exampleDatabase: ExampleDatabase, private _paginator: MdPaginator, private _sort: MdSort) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._paginator.page,
      this._sort.mdSortChange
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      const data = this.getSortedData();

      // Grab the page's slice of data.
      const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
      return data.splice(startIndex, this._paginator.pageSize);
    });
  }

  disconnect() { }

  /** Returns a sorted copy of the database data. */
  getSortedData(): UserData[] {
    const data = this._exampleDatabase.data.slice();
    if (!this._sort.active || this._sort.direction == '') { return data; }

    return data.sort((a, b) => {
      let propertyA: number | string = '';
      let propertyB: number | string = '';

      switch (this._sort.active) {
        case 'userId': [propertyA, propertyB] = [a.id, b.id]; break;
        case 'userName': [propertyA, propertyB] = [a.name, b.name]; break;
        case 'progress': [propertyA, propertyB] = [a.progress, b.progress]; break;
        case 'color': [propertyA, propertyB] = [a.color, b.color]; break;
        case 'url': [propertyA, propertyB] = [a.url, b.url]; break;
      }

      let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
      let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

      return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'asc' ? 1 : -1);
    });
  }


}
/* Structure */
.example-container {
  display: flex;
  flex-direction: column;
  max-height: 500px;
  min-width: 300px;
}

.example-header {
  min-height: 64px;
  display: flex;
  align-items: center;
  padding-left: 24px;
  font-size: 20px;
}

.mat-table {
  overflow: auto;
}
md-row:hover{
  background-color: #f3f3f3;
}
<div class="example-container mat-elevation-z8">

  <md-table #table mdSort [dataSource]="dataSource">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->
    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>

    <!-- ID Column -->
    <ng-container cdkColumnDef="userId">
      <md-header-cell *cdkHeaderCellDef md-sort-header> ID </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="progress">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Progress </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="userName">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Name </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
    </ng-container>

    <!-- Color Column -->
    <ng-container cdkColumnDef="color">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Color </md-header-cell>
      <md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell>
    </ng-container>

    <!-- Url Column -->
    <ng-container cdkColumnDef="url">
      <md-header-cell *cdkHeaderCellDef md-sort-header> Audio </md-header-cell>
      <md-cell *cdkCellDef="let row" >
         <button md-button (click)="callAudioEvent(row.url)" [style.color]="row.color">Listen..</button>
        </md-cell>
    </ng-container>

  </md-table>

  <md-paginator #paginator [length]="exampleDatabase.data.length" [pageIndex]="0" [pageSize]="5" [pageSizeOptions]="[5, 10, 25,50, 100]">
  </md-paginator>
</div>
1
Elvin Garibzade