我尝试使用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);
});
}
如何使排序,过滤和分页起作用?
答案 0 :(得分:18)
在01/29/2018编辑:有关材料数据表的文章已经编写并可以看到here,它包括服务器分页,过滤和排序,可能更多最新的代码比我下面的代码更新,因为很多人都在访问这篇文章我觉得真的需要这个,希望它能帮助你们所有人,玩得开心。
编辑:plunkr示例不再有效,所以我在stackblitz上重新实现了最新的材料发布(截至此编辑,测试版12)
注意:如果您使用的是较旧版本的素材,则需要将mat
前缀更改回md
此plunkr example(不再起作用,请参阅上面的链接以了解正在运行的版本)将向您显示包含您正在寻找的所有实施的表格。
您可以看到它是如何通过依赖注入实现的:
const displayDataChanges = [
this._exampleDatabase.dataChange,
this._sort.mdSortChange,
this._filterChange,
this._paginator.page,
];
Observable.merge(...displayDataChanges).map
过滤数据,sortData()
方法对其进行排序,分页器根据过滤数据的长度生成页数。
答案 1 :(得分:1)
这是分页和排序的用途:
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);
});
}
}
&#13;
/* 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;
}
&#13;
<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>
&#13;