【问题标题】:How to use the MatTableDataSource with an observable?如何将 MatTableDataSource 与 observable 一起使用?
【发布时间】:2020-01-06 06:52:45
【问题描述】:

我正在使用 mat-table,我正在尝试将 MatTableDataSource 与 observable 一起使用(我从 Web 服务获取数据),但我不知道如何配置 MatTableDataSource em>MatTableDataSource 使用 observable 而不是数组。

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

这是我到目前为止所拥有的,但我不知道这是否是使用带有 observable 的 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;
        });
}

【问题讨论】:

  • 我认为根据 Angular Material 文档,这是正确的解决方案。如果要将数据存储到 dataSource 中,则必须使用 new MatTableDataSource()
  • 在这篇文章中查看我的答案stackoverflow.com/questions/54691541/… 完全可以使用 MatTableDataSource 的 observable

标签: angular angular-material observable angular8 mat-table


【解决方案1】:

将 MatTableDataSource 用作 Observable:

你可以pipe你的 observable:

thingsAsMatTableDataSource$: Observable<MatTableDataSource<Thing>>  =
  getThings().pipe(
    map(things => {
      const dataSource = new MatTableDataSource<Thing>();
      dataSource.data = things;
      return dataSource;
}));

如上所述,您可以在模板中的 observable 上使用异步管道作为数据源:

[dataSource]="thingsAsMatTableDataSource$ | async"

这样你就不必订阅了,仍然可以享受 mat-table 排序等...

【讨论】:

    【解决方案2】:

    这是一种解决方法,因为 MatTableDataSource 不支持 Observable 作为数据源

    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
    }
    

    示例:stackblitz

    【讨论】:

    • 你能在你的代码中添加一些解释吗?
    • 我在帖子中做了一些更改,并在 stackblitz 上添加了示例
    【解决方案3】:

    您应该能够在班级级别更新一次MatTableDataSource,然后在ngOnInit 中使用data 设置器。

    dataSource = new MatTableDataSource<Thing>();
    @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
    @ViewChild(MatSort, { static: true }) sort: MatSort;
    
    ngOnInit() {
        getThings().subscribe(things => {
            this.dataSource.data = things;
            this.dataSource.paginator = this.paginator;
            this.dataSource.sort = this.sort;
        });
    }
    

    【讨论】:

    • 请注意,设置数据后设置排序有点慢:stackoverflow.com/a/51296374/1596352(在我自己的应用程序中,它并没有像链接中那样极端,但仍然做了一个明显不同。
    • 是的,我建议将订阅放在ngAfterViewInit 函数下。 :D
    • 不想在组件中订阅,在模板中使用异步获取数据怎么办?
    • 设置分页器和排序必须在 ngAfterViewInit 中完成
    【解决方案4】:

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

    我在这篇文章中解释了基本概念:
    https://medium.com/@matheo/reactive-datasource-for-angular-1d869b0155f6

    在示例代码中,您可以看到我如何从 Firebase 数据库中获取项目并操作分页。示例 repo 中的排序和过滤器
    我希望你喜欢它并给我你的意见;)

    【讨论】:

      【解决方案5】:

      你也可以使用 observable,只是 (*)

      [dataSource]="dataSource|async"
      

      (*) 你真的不需要使用管道异步

      查看stackblitz 中的示例,我将文档的第一个示例替换为

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

      【讨论】:

      • 但是使用排序和分页功能并不是那么容易。
      • sorry,没关系,dataSource可以是MatTableDataSource,也可以是数组或observable,但只有MatTableDataSource才能排序;
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-23
      • 2021-07-07
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-03
      相关资源
      最近更新 更多