在 Mat-Table (Angular) 中显示分页数据
Displaying Paginated Data in Mat-Table (Angular)
我有一个 CRUD REST API,它将分页数据发送到客户端。考虑以下数据接口:
export interface LCKData {
// Some basic type fields from DB
}
export interface LCKPageData {
content: LCKData[],
pageable: any,
totalElements: number,
totalPages: number,
last: boolean,
numberOfElements: number,
size: number,
number: number,
sort: any,
first: boolean,
empty: boolean
}
第二个接口是来自 Spring 启动 Web 应用程序的标准分页数据。我使用这个结构来设置 Paginator 组件属性,即总页数。
我使用这两个服务来获取数据并创建数据源:
let LCKBaseAddress: string = "...";
@Injectable()
export class LockService {
constructor(private http: HttpClient) { }
findLCK(sortColumn = "sysTime", sortOrder = 'desc',
pageNumber = 0, pageSize = 10): Observable<LCKPageData> {
return this.http.get(LCKBaseAddress, {
params: new HttpParams()
.set('q', sortColumn)
.set('d', sortOrder)
.set('p', pageNumber.toString())
.set('s', pageSize.toString())
}).pipe(map(res => {
res['payload'] = res;
return res["payload"];
}))
};
}
并且:
export class MainService extends DataSource<LCKData>{
private loadingSubject = new BehaviorSubject<boolean>(false);
private pageSubject = new BehaviorSubject<LCKData[]>([]);
private locks$ = new Observable<LCKPageData>();
constructor(private lockService: LockService) {
super();
};
connect(collectionViewer: CollectionViewer): Observable<LCKData[]> {
return this.locks$.pipe(pluck("content"));
}
disconnect(collectionViewer: CollectionViewer): void {
this.loadingSubject.complete();
this.pageSubject.complete();
}
loadLCK(sortColumn = "sys_time", sortOrder = 'desc',
pageNumber = 0, pageSize = 10) {
this.lockService.findLCK(sortColumn, sortOrder, pageNumber, pageSize).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
.subscribe(lcks => this.pageSubject.next(lcks['content']));
}
}
最后是 table 组件:
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
public columns: string[];
dataSource: MainService;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(public lock: LockService) {}
ngOnInit(): void {
this.dataSource = new MainService(this.lock);
this.dataSource.loadLCK();
this.columns = [ // Some columns //];
}
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
merge(this.sort.sortChange, this.paginator.page)
.pipe(
tap(() => this.loadLessonsPage())
)
.subscribe();
}
loadLessonsPage() {
this.dataSource.loadLCK(
'sysTime',
this.sort.direction,
this.paginator.pageIndex,
this.paginator.pageSize);
}
}
和模板:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z2" matSort matSortActive="sysTime"
matSortDirection="desc" matSortDisableClear>
// Column and row definition
代码运行没有任何错误,但 table 中没有显示任何内容。
之前我用非分页数据测试了相同的方法,一切正常,服务器响应 List 而不是 LCKPageData。
我用Angular10.
有什么想法吗?
您的 connect()
方法 returns 一个从不发射的可观察对象!
与其将 locks$
初始化为新的可观察对象,不如将其定义为 pageSubject
。
private locks$: Observable<LCKData[]> = this.pageSubject.asObservable();
无需使用 pluck
,因为您已经将 content
属性 发送到主题 (this.pageSubject.next(lcks['content'])
):
connect(collectionViewer: CollectionViewer): Observable<LCKData[]> {
return this.locks$;
}
我有一个 CRUD REST API,它将分页数据发送到客户端。考虑以下数据接口:
export interface LCKData {
// Some basic type fields from DB
}
export interface LCKPageData {
content: LCKData[],
pageable: any,
totalElements: number,
totalPages: number,
last: boolean,
numberOfElements: number,
size: number,
number: number,
sort: any,
first: boolean,
empty: boolean
}
第二个接口是来自 Spring 启动 Web 应用程序的标准分页数据。我使用这个结构来设置 Paginator 组件属性,即总页数。
我使用这两个服务来获取数据并创建数据源:
let LCKBaseAddress: string = "...";
@Injectable()
export class LockService {
constructor(private http: HttpClient) { }
findLCK(sortColumn = "sysTime", sortOrder = 'desc',
pageNumber = 0, pageSize = 10): Observable<LCKPageData> {
return this.http.get(LCKBaseAddress, {
params: new HttpParams()
.set('q', sortColumn)
.set('d', sortOrder)
.set('p', pageNumber.toString())
.set('s', pageSize.toString())
}).pipe(map(res => {
res['payload'] = res;
return res["payload"];
}))
};
}
并且:
export class MainService extends DataSource<LCKData>{
private loadingSubject = new BehaviorSubject<boolean>(false);
private pageSubject = new BehaviorSubject<LCKData[]>([]);
private locks$ = new Observable<LCKPageData>();
constructor(private lockService: LockService) {
super();
};
connect(collectionViewer: CollectionViewer): Observable<LCKData[]> {
return this.locks$.pipe(pluck("content"));
}
disconnect(collectionViewer: CollectionViewer): void {
this.loadingSubject.complete();
this.pageSubject.complete();
}
loadLCK(sortColumn = "sys_time", sortOrder = 'desc',
pageNumber = 0, pageSize = 10) {
this.lockService.findLCK(sortColumn, sortOrder, pageNumber, pageSize).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
.subscribe(lcks => this.pageSubject.next(lcks['content']));
}
}
最后是 table 组件:
@Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
public columns: string[];
dataSource: MainService;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(public lock: LockService) {}
ngOnInit(): void {
this.dataSource = new MainService(this.lock);
this.dataSource.loadLCK();
this.columns = [ // Some columns //];
}
ngAfterViewInit() {
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
merge(this.sort.sortChange, this.paginator.page)
.pipe(
tap(() => this.loadLessonsPage())
)
.subscribe();
}
loadLessonsPage() {
this.dataSource.loadLCK(
'sysTime',
this.sort.direction,
this.paginator.pageIndex,
this.paginator.pageSize);
}
}
和模板:
<table mat-table [dataSource]="dataSource" class="mat-elevation-z2" matSort matSortActive="sysTime"
matSortDirection="desc" matSortDisableClear>
// Column and row definition
代码运行没有任何错误,但 table 中没有显示任何内容。
之前我用非分页数据测试了相同的方法,一切正常,服务器响应 List
我用Angular10.
有什么想法吗?
您的 connect()
方法 returns 一个从不发射的可观察对象!
与其将 locks$
初始化为新的可观察对象,不如将其定义为 pageSubject
。
private locks$: Observable<LCKData[]> = this.pageSubject.asObservable();
无需使用 pluck
,因为您已经将 content
属性 发送到主题 (this.pageSubject.next(lcks['content'])
):
connect(collectionViewer: CollectionViewer): Observable<LCKData[]> {
return this.locks$;
}