Angular 如何将MatTableDataSource与可观测数据一起使用?

Angular 如何将MatTableDataSource与可观测数据一起使用?,angular,angular-material,observable,angular8,mat-table,Angular,Angular Material,Observable,Angular8,Mat Table,我正在使用mat表,并尝试使用MatTableDataSource和observable(我从web服务获取数据),但我不知道如何配置MatTableDataSource以使用observable而不是数组 这个问题的唯一解决方案是订阅ngOnInit方法中的可观测数据,并在新数据到达时始终创建一个新的MatTableDataSource吗 这是我到目前为止所拥有的,但我不知道这是否是使用MatTableDataSource和可观测数据源的正确解决方案 dataSource: MatTableD

我正在使用mat表,并尝试使用MatTableDataSource和observable(我从web服务获取数据),但我不知道如何配置MatTableDataSource以使用observable而不是数组

这个问题的唯一解决方案是订阅ngOnInit方法中的可观测数据,并在新数据到达时始终创建一个新的MatTableDataSource吗

这是我到目前为止所拥有的,但我不知道这是否是使用MatTableDataSource和可观测数据源的正确解决方案

dataSource: MatTableDataSource<Thing>;
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;

ngOnInit() {
    getThings().subscribe(things => {
        this.dataSource = new MatTableDataSource(things);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
        });
}
数据源:MatTableDataSource;
@ViewChild(MatPaginator,{static:true})paginator:MatPaginator;
@ViewChild(MatSort,{static:true})sort:MatSort;
恩戈尼尼特(){
getThings().subscribe(things=>{
this.dataSource=新MatTableDataSource(things);
this.dataSource.paginator=this.paginator;
this.dataSource.sort=this.sort;
});
}

您也可以使用可观察的,只是(*)

(*)实际上,您不需要使用管道异步

请参见中的示例,其中我将文档的第一个示例替换为

dataSource = of(ELEMENT_DATA).pipe(delay(1000));

我为此发布了一个库:
@matheo/datasource

我将解释本文中的基本概念:

在示例代码中,您可以看到我如何从Firebase数据库获取项目并操作分页。示例repo中的排序和筛选

我希望你喜欢它,并给我你的意见;)

您应该能够在类级别新建一次
MatTableDataSource
,然后使用
ngOnInit
中的
数据设置器

dataSource=new MatTableDataSource();
@ViewChild(MatPaginator,{static:true})paginator:MatPaginator;
@ViewChild(MatSort,{static:true})sort:MatSort;
恩戈尼尼特(){
getThings().subscribe(things=>{
this.dataSource.data=事物;
this.dataSource.paginator=this.paginator;
this.dataSource.sort=this.sort;
});
}

这是一个解决方案,因为MatTableDataSource不支持作为数据源的可观察性

import { MatTableDataSource } from '@angular/material';
import { Observable, Subscription } from 'rxjs';
import { SomeInterface} from './some.interface';

export class CustomDataSource extends MatTableDataSource<SomeInterface> {

    private collection: SomeInterface[] = [];

    private collection$: Subscription;

    constructor(collection: Observable<SomeInterface[]>) {
        super();
        this.collection$ = collection.subscribe(data => {
           this.data = data; // here you have to adjust the behavior as needed
        });
    }

   disconnect() {
     this.collection$.unsubscribe();
     super.disconnect();
   }
}

示例:

我认为根据角材料文档,这是正确的解决方案。如果要将数据存储到dataSource中,则必须使用新的MatTableDataSource(),但排序和分页功能并不容易使用。对不起,您可以,dataSource可以是MatTableDataSource,也可以是数组或可观察数据,但您只能在MatTableDataSource中对其进行排序;请注意,设置数据后设置排序的速度要慢一些:(在我自己的应用程序中,它并没有在链接中那么极端,但仍然有明显的不同。是的,我建议将订阅放在
ngAfterViewInit
函数下。:dw如果我不想在组件中订阅它并在模板中使用async来获取数据,怎么办?设置分页器和排序必须在ngAfterVie中完成你能给你的代码添加一些解释吗?我在我的帖子中做了一些更改,并在stackblitz上添加了一些示例
import { MatTableDataSource } from '@angular/material';
import { Observable, Subscription } from 'rxjs';
import { SomeInterface} from './some.interface';

export class CustomDataSource extends MatTableDataSource<SomeInterface> {

    private collection: SomeInterface[] = [];

    private collection$: Subscription;

    constructor(collection: Observable<SomeInterface[]>) {
        super();
        this.collection$ = collection.subscribe(data => {
           this.data = data; // here you have to adjust the behavior as needed
        });
    }

   disconnect() {
     this.collection$.unsubscribe();
     super.disconnect();
   }
}
dataSource: CustomDataSource;

ngOnInit(): void {
  const observableData$ = getData();
  this.dataSource = new CustomDataSource(observableData$);
  // this.dataSource.sort = this.sort; // add sorting or filter
}