1

PS:我是 Angular 和 JS 的新手。

在我的新 angular 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文件中,我有一些属性和connect,disconnect方法定义如下:

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
 }

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

不确定我是否能够正确地说出这些话,但我希望读者能明白我的意思。任何指示将不胜感激。

更新

如果我定义dataSourceTestTableDataSource,如下:

dataSource: TestTableDataSource;

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

4

3 回答 3

4

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

我的建议是:

  • 完全删除TestTableDataSource
  • 当你的 api中ngOnInit的数组被填充时(让我们称之为它myArr),你只需要从这个数组初始化表的数据源,就像这样this.dataSource = new MatTableDataSource(myArr);

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

于 2019-07-16T11:39:44.670 回答
4

如果您不需要分页、排序或过滤,那么@leopal 的回答就可以了。如果您确实需要这些功能,请查看Angular Material博客条目: Angular Material Data Table: A Complete Example (Server Pagination, Filtering, Sorting)

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

页:

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 );
    }*/  
};
于 2019-10-20T04:44:05.860 回答
-2

您正在创建不同的 mat-table

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

@ViewChild('matTable') matTable: MatTable;

ngAfterViewInit() {
  this.matTable.data = yourData;
}

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

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

然后 changeDetection 将为您完成剩下的工作

于 2019-07-16T11:16:59.733 回答