6

这是我的爱好项目,由于这个问题,它已经停滞了一段时间。这可能是一个简单的问题,但我对 Angular 和 JS 的了解相当有限。不过我的代码在下面(我已经缩短了一点),它在某种程度上是有效的。它正在从服务器获取数据,然后显示在客户端。那里没有问题,但是现在当我尝试进行客户端过滤时,什么也没有发生。字面上地。我正在输入过滤器输入框,但什么也没有。不过滤表行。

我在这里想知道两件事:

  1. 我是否使用了正确的方法(我可以扩展 MatTableDataSource)吗?
  2. 我做错了什么(如果我可以扩展 MatTableDataSource)?

我的数据.ts

export interface MyData {
    id: number;
    description: string;
}

MyData.service.ts

export class MyService {

    constructor(private http: HttpClient) { }

    getData(): Observable<MyData[]> {
        return this.http.get...
    }
}

我的数据.datasource.ts

export class MyDataSource extends MatTableDataSource<MyData> {

    private mySubject = new BehaviorSubject<MyData[]>([]);

    constructor(private myService: MyService) { super(); }

    loadData() {
        this.myService.getData()
        .pipe(catchError(() => of([])))
        .subscribe(data => this.mySubject.next(data));
    }

    connect(): BehaviorSubject<myData[]> {
        return this.mySubject;
    }

    disconnect(): void {
        this.mySubject.complete();
    }
}

MyData.component.ts

export class MyDataComponent implements OnInit {

    displayedColumns= ["id", "description"];
    dataSource: MyDataSource;

    constructor(private myService: MyService) { }

    ngOnInit() {
        this.dataSource = new MyDataSource(this.myService);
        this.dataSource.loadData();
    }

        applyFilter(filterValue: string) {
            this.dataSource.filter = filterValue.trim().toLowerCase();
        }
}

MyData.component.html

<mat-form-field>
    <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>

<mat-table [dataSource]="dataSource">

    <ng-container matColumnDef="id">
        <mat-header-cell *matHeaderCellDef>ID</mat-header-cell>
        <mat-cell *matCellDef="let data">{{data.id}}</mat-cell>
    </ng-container>

    <ng-container matColumnDef="description">
        <mat-header-cell *matHeaderCellDef>Description</mat-header-cell>
        <mat-cell *matCellDef="let data">{{data.description}}</mat-cell>
    </ng-container>

</mat-table>
4

1 回答 1

1

是的,如果您想对数据进行更多控制,例如自定义排序、过滤、分页和数据的实时流/操作,您可以扩展数据源。如果没有,您可以使用材料网站中提供的默认数据源类

https://material.angular.io/components/table/overview

如上面的材料站点所述,如果您想做更复杂的事情,您可以扩展数据源类

Advanced data sources
The simplest way to provide data to your table is by passing a data array. More complex use-cases may benefit from a more flexible approach involving an Observable stream or by encapsulating your data source logic into a DataSource class.

这是一个关于如何使用它的更复杂的示例。

下面的代码是数据源的构造函数。其中包含分页器、数据服务和 Mat 排序。

  constructor(public _dataService: DataService,
              public _paginator: MatPaginator,
              public _sort: MatSort) {
    super();
    // Reset to the first page when the user changes the filter.
    this._filterChange.subscribe(() => this._paginator.pageIndex = 0);
  }

然后你将实现连接类。此连接类是一个可观察对象,您的 mat-table 将订阅此可观察对象并根据可观察对象返回的内容显示数据

  connect(): Observable<Array<Data>> {
    // Listen for any changes in the base data, sorting, filtering, or 
    //pagination the below object types are all observable/behaviour 
    //subjects
    const displayDataChanges = [
      this._dataService.entryDataChange,
      this._sort.sortChange,
      this._filterChange,
      this._paginator.page
    ]; 
    data: YourCurrentData;
    // Merge all the observable into one stream
    return Observable.merge(...displayDataChanges).map((n) => {
      // If is filter data observer do action
      // If is a sort observer emitting data do action
      // If is new incoming data do action
      // If is a paginator observable emmiting data do action
      // Return filtered, sorted, and paged data that you want to display
      // on your current page. 
    });
  }

上面的例子使用了旧的 rxjs 版本。但希望你明白它背后的逻辑!

于 2018-10-26T03:09:06.363 回答