ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 没有setTimeOut,MatSort和MatPaginator不起作用

2019-10-02 17:37:46  阅读:271  来源: 互联网

标签:javascript angular sorting pagination angular-material


我有一个来自端点的数据并将其放入MatTableDataSource.我能够让它适用于MatSort和MatPaginator,但需要使用setTimeOut,这似乎不是一个正确的方法来做到这一点.如果我删除它,它会抱怨’无法读取sort undefined属性’,我认为这是由于它尚未初始化.

我也尝试过:

>将其移动到afterviewinit,但数据在之后加载
afterviewinit被调用,所以它仍然无法正常工作
>在this.datasource =之后使用this.changeDetectorRef.detectChanges()
新……也行不通

这是我当前的代码(正在运行,但使用settimeout)

<div *ngIf="!isLoading">
    <div *ngFor="let record of renderedData | async" matSort>

    // ... some html to show the 'record'

    <mat-paginator #paginator
        [pageSizeOptions]="[5, 10, 20]">
    </mat-paginator>
</div>

组件

export class ResultsComponent implements OnInit, OnDestroy, AfterViewInit {
    dataSource: MatTableDataSource<any> = new MatTableDataSource();
    renderedData: Observable<any>;

    @ViewChild(MatPaginator) paginator: MatPaginator;
    @ViewChild(MatSort) sort: MatSort;

    constructor(some service) {}

    ngOnInit() {
        const accountId = someOtherService.getAccountId();
        this.someService.getData(accountId)
            .subscribe((myData) => {
                    this.dataSource = new MatTableDataSource(myData);

                    // it won't work properly if it is not wrapped in timeout
                    setTimeout(() => {
                        this.dataSource.paginator = this.paginator;
                        this.sort.sort(<MatSortable>({id: 'created_on', start: 'desc'}));
                        this.dataSource.sort = this.sort;
                    });

                    this.renderedData = this.dataSource.connect();
                }
            });
    }

    ngAfterViewInit() {
    }

    ngOnDestroy(): void {
        if (this.dataSource) { this.dataSource.disconnect(); }
    }
}

上面的代码对我有用,我只是在寻找正确的方法,如果可能的话不使用settimeout.

解决方法:

这里有几个生命周期计时问题,当你考虑它时,这是正确的.

MatSort是视图的一部分,因此在OnInit期间它没有“准备好” – 它是未定义的.因此,尝试使用它会引发错误.

MatSort在AfterViewInit中已经准备就绪,但是在执行排序之后需要将排序“应用”到数据源这一事实使事情变得更加复杂,并且这会通过“连接”到的renderData触发对视图的更改数据源.因此,您最终会遇到ExpressionChangedAfterItHasBeenCheckedError,因为视图初始化生命周期尚未完成,但您已尝试更改它.

因此,在视图准备就绪之前,您无法进行排序,并且当您收到视图已准备好的通知时,您无法应用排序.您唯一能做的就是等到组件初始化生命周期结束.你可以使用setTimeout()来做到这一点.

如果没有setTimeout(),我认为没有任何解决这两个问题的方法,所以在这种情况下,无论是从OnInit还是AfterViewInit调用它都无关紧要.

关于您的代码的其他一些观察:

您无需在订阅中创建MatTableDataSource的新实例.您可以将结果数据分配给已创建的数据源:

this.dataSource.data = myData;

这使您不必在以后将渲染数据连接到数据源,因此您可以在初始化数据源时执行此操作:

dataSource: MatTableDataSource<any> = new MatTableDataSource();
renderedData: Observable<any> = this.dataSource.connect();

标签:javascript,angular,sorting,pagination,angular-material
来源: https://codeday.me/bug/20191002/1843573.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有