在角度 7 中为角度材质表设置自定义数据源



P.S:我是Angular和JS的新手。

在我的新角度 7 项目中,我有一个材料数据表组件。从 REST API 中,在进行GET调用后,我能够填充所需对象的数组。这一切都发生在组件的ngOnInit方法中。(不包括代码,因为它无关紧要)。

我的问题是,如何将数组绑定到数据表的dataSource?在数据表的 HTML 中,我在顶部有:

<table mat-table [dataSource]="dataSource" matSort aria-label="Elements">
....
....
<td mat-cell *matCellDef="let row">{{row.id}}</td>
</...>

..DataSource.ts文件中,我有一些属性和connectdisconnect方法定义如下:

export class TestTableItem {
id: number; 
}
export class TestTableDataSource extends DataSource<TestTableItem> {
paginator: MatPaginator;
sort: MatSort;
constructor(private TestArray: any[]) {
super();
}
connect(collections: CollectionViewer): Observable<TestTableItem[]> {
return observableOf<TestTableItem[]>(this.TestArray);
}
disconnect() {}

component.ts中,我声明了dataSource属性,如上所述,我在ngOnInit()方法中填充数组,如下所示:

private myCollection: TestTableItem[] = [];
dataSource = new MatTableDataSource(this.myCollection);
ngOnInit() {
...
//adding new item to myCollection
}

那么,最后,如何将数组绑定到表中?我试图在ngOnInIt方法中将new TestTableDataSource(this.myCollection);传递给this.dataSource,但由于dataSourceTestTableDataSource是不同类型的,因此失败了。

不确定我是否能够正确地表达这些词,但我希望读者能理解我的观点。任何指示将不胜感激。

更新

如果我将dataSource定义为TestTableDataSource,如下所示:

dataSource: TestTableDataSource;

代码工作正常。但是,该表仍为空。有趣的是,进行此更改还会删除表的所有列。表格将变为完全空白。为什么即使myCollection不是空的也会发生这种情况?

无需扩展DataSource,即可将从 REST API 返回的数组绑定到 mat 表的数据源。

我的建议是:

  • 完全删除TestTableDataSource
  • ngOnInit当填充来自 API 的数组(我们称之为myArr)时,您只需要从该数组初始化表的数据源,如下所示this.dataSource = new MatTableDataSource(myArr);

在此之后,您的数组内容将呈现为 mat 表的数据。

如果您不需要分页、排序或过滤,那么@leopal的答案就可以了。 如果您确实需要这些功能,请查看Angular Material博客条目: 角度材料数据表:完整示例(服务器分页、过滤、排序)。

它非常完整且解释得很好 - 而且太长了,甚至无法涵盖这里的亮点。 我看到的一个差距是如何在应用过滤器后更新分页器的总长度......下面是我的工作代码。

页:

export class Page<T> extends Array<T> {
public static readonly DEFAULT_PAGE_SIZE: number = 10;
pageIndex: number;
pageSize: number;
totalCount: number;
constructor( pgIx?: number, pgSize?: number, tot?: number, items?: T[] )
{
super();
this.pageIndex = pgIx ? pgIx : 0;
this.pageSize = pgSize ? pgSize : 0;
this.totalCount = tot ? tot : 0;
if ( items && items.length > 0 ) {
this.push( ...items );
}
}
}

表状态:

import { Observable, BehaviorSubject, Observer } from "rxjs";
import { map, catchError, finalize,
debounceTime, distinctUntilChanged, startWith, tap, delay 
} from "rxjs/operators";
import { CollectionViewer, DataSource } from "@angular/cdk/collections";
import { MatPaginator }                 from '@angular/material';
import { MyError } from '../model/error';
import { Page } from '../model/page';
export class MyTableState<T> implements DataSource<T>, Observer<Page<T>> 
{
private items = new BehaviorSubject<Page<T>>( new Page<T>() );
private loading = new BehaviorSubject<boolean>(false);
private err = new BehaviorSubject<DruidError>( new DruidError(0, '') );

protected paginator: MatPaginator;
items$ = this.items.asObservable();
loading$ = this.loading.asObservable();
error$ = this.err.asObservable();

closed = false;

constructor( protected itemType: string ) {
}

haveError() : boolean {
const derr = this.err.getValue();
if ( derr && (derr.status !== 0 || derr.message) ) {
return true;
}
return false;
}
errorStatus() : number {
const derr = this.err.getValue();
if ( derr ) {
return derr.status;
}
return 0;
}
errorMessage() : string {
const derr = this.err.getValue();
if ( derr ) {
return derr.message;
}
return '';
}
noResults() : boolean {
const results = this.items.getValue();
return !results || results.length == 0;
}
isLoading() : Observable<boolean> {
return this.loading$;
}
totalCount() : number {
const cnt = this.items.getValue();
return ( cnt ? cnt.totalCount : 0 );
}
next( results: Page<T> ) : void {
console.debug( "Found items: ", this.itemType, results );
if ( this.paginator ) {
this.paginator.length = results.totalCount;
}
this.items.next( results );
}
error( errr: any ) : void {
console.error( "Error loading items: ", this.itemType, errr );
this.err.next( errr );
}
complete() : void {
console.debug( "Done loading items.", this.itemType );
this.loading.next( false );
}
addItem( item: T ) : void {
this.items.value.unshift( item );
}
connect( collectionViewer: CollectionViewer ) : Observable<Page<T>> {
this.closed = false;
return this.items$;
}
disconnect( collectionViewer: CollectionViewer ): void {
this.closed = true;
this.items.complete();
this.loading.complete();
this.err.complete();
}

protected preLoad() : void {
this.err.next( new DruidError(0,'') );
this.loading.next( true );
}
setPaginator( pgntr: MatPaginator ) : void {
this.paginator = pgntr;
}
/* In a derived class implement this and call it from your containing 
* components in response to filter input, etc.
loadXyzs( offset: number = 0, limit: number = 10, predicates?: any ) : void
{
this.preLoad();
this.xyzService
.searchXyzs( offset, limit, predicates )
.subscribe( this );
}*/  
};

您正在创建不同的垫表

您可以使用 @ViewChild 指令获取对 HTML 中呈现的 mat-table 的引用

@ViewChild('matTable') matTable: MatTable;
ngAfterViewInit() {
this.matTable.data = yourData;
}

或者,您可以在 HTML 中使用 mat-table 数据源输入:

<table mat-table [dataSource]="yourDataSource">
// Your HTML
</table

然后更改检测将为您完成剩下的工作

最新更新