Angular |打字稿 |数据 Table 不是 Paging/Sorting
Angular | Typescript | Data Table not Paging/Sorting
我在处理数据 table 时遇到了一些问题 - 背景是我需要通过可观察的订阅同时进行多个 API 调用,然后将这些调用合并到一个数据结构中。我需要将这些数据传递到数据 Table 中,我成功地这样做了,但是,一旦加载了数据,我的 ViewChild
for MatPaginator
和 MatSort
就没有了检测到一个变化,所以我的分页器和排序功能的值就好像没有数据存在,即页面中的 0 值。
在 ngAfterViewInit 完成后,我的数据加载仍在执行,所以这里有什么我需要做的超出常规的事情吗?
我尝试过的一些东西:
- 添加
ChangeDetectorRef
和运行ChangeDetectorRef.DetectChanges()
无济于事
- 处理数据以便函数运行 post 完成 API 调用
- 使用 NgZone
希望这对我的代码更有意义(我试图通过删除函数来保持简短,但多个函数正在将值写入数据源数组 (this.dataHashArray
)
数据-table.html
<div class="global-container-padding">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search Shares">
</mat-form-field>
<div class="data-container">
<table mat-table [dataSource]="dataSource" matSort class="share-table mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<!-- SVMName Column -->
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let row"> {{row.Name}} </td>
</ng-container>
<!-- shareName Column -->
<ng-container matColumnDef="shareName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Share Name </th>
<td mat-cell *matCellDef="let row"> {{row.shareName}} </td>
</ng-container>
<!-- storagePath Column -->
<ng-container matColumnDef="storagePath">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Storage Path </th>
<td mat-cell *matCellDef="let row"> {{row.storagePath}} </td>
</ng-container>
<!-- Protocol Column -->
<ng-container matColumnDef="Protocol">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Protocol </th>
<td mat-cell *matCellDef="let row"> {{row.Protocol}} </td>
</ng-container>
<!-- exists Column -->
<ng-container matColumnDef="exists">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Exists </th>
<td mat-cell *matCellDef="let row"> {{row.exists}} </td>
</ng-container>
<ng-container matColumnDef="HostId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Host ID </th>
<td mat-cell *matCellDef="let row"> {{row.HostId}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)"></tr>
</table>
<mat-paginator [length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions">
</mat-paginator>
</div>
</div>
数据-table.ts
import {AfterViewInit, Component, Injectable, NgZone, OnInit, ViewChild} from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, MatSort } from '@angular/material';
@Injectable()
export class DataComponent implements OnInit, AfterViewInit {
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild(MatSort, {static: true}) sort: MatSort;
private length = 0;
private pageSize = 25;
private pageSizeOptions: number[] = [5, 10, 25, 100];
constructor(
private ShareService: ShareService,
private _snackBar: MatSnackBar,
private ngZone: NgZone
) {
this.dataHashArray = [];
}
public ngOnInit(): void {
this.displayedColumns = ['select', 'Name', 'shareName', 'storagePath', 'Protocol', 'exists', 'HostId'];
if(this.dataHashArray == null) {
this.dataSource = new MatTableDataSource<DataHash>([]);
} else {
this.dataSource = new MatTableDataSource<DataHash>(this.dataHashArray);
}
for(let nx = 0; nx < this.store.length; nx++) {
if(this.store[nx]['type'] == 'nas') {
this.loadApp(this.store[nx]);
}
}
}
public ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
this.ngZone.run(() => {
this.ShareService.getShares(this.Token, '').subscribe( shares => {
this.DataHashBuild(shares, this.Token, HostID);
});
});
public DataHashBuild(Shares: string, Token: string | null, HostId: string | null) {
this.ShareService.getVserverList().subscribe(vServer => {
for (let x = 0; x < vServer.length; x++) {
this.ShareService.getShares(vServer[x]).subscribe(nShares => {
for (let i = 0; i < nShares.length; i++) {
let exists: boolean = false;
for (let j = 0; j < Shares.length; j++) {
if (Shares[j]['hostname'] == `${vServer[x]}_cifs` &&
Shares[j]['exportPoint'] == nShares[i]['share-name']) {
exists = true;
let paramStr = `?host_id=${Shares[j]['hostId']}&share_id=${Shares[j]['id']}`;
this.ShareService.getShare(Token, paramStr).subscribe(getShare => {
console.log(getShare);
});
}
}
this.dataHashArray.push({
SVMName: vServer[x],
shareName: `\\${nShares[i]['cifs-server']}\${nShares[i]['share-name']}`,
storagePath: `/${nShares[i]['volume']}`,
Protocol: 'SMB',
exists: exists,
HostId: HostId
});
this.dataSource = new MatTableDataSource<DataHash>(this.dataHashArray);
this.renewDataSource();
}
});
}
});
}
public renewDataSource() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
ShareService.ts
public getVserverList(): Observable<vServerInterface>{
return this.http.post(url, data, {headers: headers, responseType: 'text'})
.pipe(map(message => {
xmlObj = this.parseXml(message);
for (let i = 0; i < xmlObj.getElementsByTagName('vserver-name').length; i++) {
outputArray.push(xmlObj.getElementsByTagName('vserver-name')[i].textContent);
}
return outputArray;
}));
}
通过订阅进行的 API 调用只是可观察的 HTTPClient GET 请求和 return http 调用。
试试这个
<mat-paginator [pageSizeOptions]="[20, 30, 50]" showFirstLastButtons></mat-paginator>
在 .ts 文件中导入以下语句
import {MatPaginator} from '@angular/material/paginator';
将下面的行复制到您的 class 构造函数
@ViewChild(MatPaginator) paginator: MatPaginator;
在您的函数中复制下面的行
this.dataSource.paginator = this.paginator;
这已通过更改解决:
import { MatPaginator } from '@angular/material';
至:
import { MatPaginator } from '@angular/material/paginator';
这同样适用于排序,即
import { MatSort} from '@angular/material/sort';
感谢@Raj 的协助。
我在处理数据 table 时遇到了一些问题 - 背景是我需要通过可观察的订阅同时进行多个 API 调用,然后将这些调用合并到一个数据结构中。我需要将这些数据传递到数据 Table 中,我成功地这样做了,但是,一旦加载了数据,我的 ViewChild
for MatPaginator
和 MatSort
就没有了检测到一个变化,所以我的分页器和排序功能的值就好像没有数据存在,即页面中的 0 值。
在 ngAfterViewInit 完成后,我的数据加载仍在执行,所以这里有什么我需要做的超出常规的事情吗?
我尝试过的一些东西:
- 添加
ChangeDetectorRef
和运行ChangeDetectorRef.DetectChanges()
无济于事 - 处理数据以便函数运行 post 完成 API 调用
- 使用 NgZone
希望这对我的代码更有意义(我试图通过删除函数来保持简短,但多个函数正在将值写入数据源数组 (this.dataHashArray
)
数据-table.html
<div class="global-container-padding">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search Shares">
</mat-form-field>
<div class="data-container">
<table mat-table [dataSource]="dataSource" matSort class="share-table mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<!-- SVMName Column -->
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let row"> {{row.Name}} </td>
</ng-container>
<!-- shareName Column -->
<ng-container matColumnDef="shareName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Share Name </th>
<td mat-cell *matCellDef="let row"> {{row.shareName}} </td>
</ng-container>
<!-- storagePath Column -->
<ng-container matColumnDef="storagePath">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Storage Path </th>
<td mat-cell *matCellDef="let row"> {{row.storagePath}} </td>
</ng-container>
<!-- Protocol Column -->
<ng-container matColumnDef="Protocol">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Protocol </th>
<td mat-cell *matCellDef="let row"> {{row.Protocol}} </td>
</ng-container>
<!-- exists Column -->
<ng-container matColumnDef="exists">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Exists </th>
<td mat-cell *matCellDef="let row"> {{row.exists}} </td>
</ng-container>
<ng-container matColumnDef="HostId">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Host ID </th>
<td mat-cell *matCellDef="let row"> {{row.HostId}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)"></tr>
</table>
<mat-paginator [length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions">
</mat-paginator>
</div>
</div>
数据-table.ts
import {AfterViewInit, Component, Injectable, NgZone, OnInit, ViewChild} from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator, MatSort } from '@angular/material';
@Injectable()
export class DataComponent implements OnInit, AfterViewInit {
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild(MatSort, {static: true}) sort: MatSort;
private length = 0;
private pageSize = 25;
private pageSizeOptions: number[] = [5, 10, 25, 100];
constructor(
private ShareService: ShareService,
private _snackBar: MatSnackBar,
private ngZone: NgZone
) {
this.dataHashArray = [];
}
public ngOnInit(): void {
this.displayedColumns = ['select', 'Name', 'shareName', 'storagePath', 'Protocol', 'exists', 'HostId'];
if(this.dataHashArray == null) {
this.dataSource = new MatTableDataSource<DataHash>([]);
} else {
this.dataSource = new MatTableDataSource<DataHash>(this.dataHashArray);
}
for(let nx = 0; nx < this.store.length; nx++) {
if(this.store[nx]['type'] == 'nas') {
this.loadApp(this.store[nx]);
}
}
}
public ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
this.ngZone.run(() => {
this.ShareService.getShares(this.Token, '').subscribe( shares => {
this.DataHashBuild(shares, this.Token, HostID);
});
});
public DataHashBuild(Shares: string, Token: string | null, HostId: string | null) {
this.ShareService.getVserverList().subscribe(vServer => {
for (let x = 0; x < vServer.length; x++) {
this.ShareService.getShares(vServer[x]).subscribe(nShares => {
for (let i = 0; i < nShares.length; i++) {
let exists: boolean = false;
for (let j = 0; j < Shares.length; j++) {
if (Shares[j]['hostname'] == `${vServer[x]}_cifs` &&
Shares[j]['exportPoint'] == nShares[i]['share-name']) {
exists = true;
let paramStr = `?host_id=${Shares[j]['hostId']}&share_id=${Shares[j]['id']}`;
this.ShareService.getShare(Token, paramStr).subscribe(getShare => {
console.log(getShare);
});
}
}
this.dataHashArray.push({
SVMName: vServer[x],
shareName: `\\${nShares[i]['cifs-server']}\${nShares[i]['share-name']}`,
storagePath: `/${nShares[i]['volume']}`,
Protocol: 'SMB',
exists: exists,
HostId: HostId
});
this.dataSource = new MatTableDataSource<DataHash>(this.dataHashArray);
this.renewDataSource();
}
});
}
});
}
public renewDataSource() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
ShareService.ts
public getVserverList(): Observable<vServerInterface>{
return this.http.post(url, data, {headers: headers, responseType: 'text'})
.pipe(map(message => {
xmlObj = this.parseXml(message);
for (let i = 0; i < xmlObj.getElementsByTagName('vserver-name').length; i++) {
outputArray.push(xmlObj.getElementsByTagName('vserver-name')[i].textContent);
}
return outputArray;
}));
}
通过订阅进行的 API 调用只是可观察的 HTTPClient GET 请求和 return http 调用。
试试这个
<mat-paginator [pageSizeOptions]="[20, 30, 50]" showFirstLastButtons></mat-paginator>
在 .ts 文件中导入以下语句
import {MatPaginator} from '@angular/material/paginator';
将下面的行复制到您的 class 构造函数
@ViewChild(MatPaginator) paginator: MatPaginator;
在您的函数中复制下面的行
this.dataSource.paginator = this.paginator;
这已通过更改解决:
import { MatPaginator } from '@angular/material';
至:
import { MatPaginator } from '@angular/material/paginator';
这同样适用于排序,即
import { MatSort} from '@angular/material/sort';
感谢@Raj 的协助。