gpt4 book ai didi

javascript - 如果没有 setTimeOut,MatSort 和 MatPaginator 将无法工作

转载 作者:太空狗 更新时间:2023-10-29 18:28:37 26 4
gpt4 key购买 nike

我有一个来自端点的数据并将其放入 MatTableDataSource 中。我能够让它为 MatSort 和 MatPaginator 工作,但需要使用 setTimeOut,这似乎不是执行此操作的正确方法。如果我删除它,它会提示“无法读取未定义的排序属性”,我认为这是因为它尚未初始化。

我也试过:

  • 将其移动到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 是 View 的一部分,因此它在 OnInit 期间没有“准备好”——它是未定义的。所以尝试使用它会引发错误。

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

因此在 View 准备好之前您不能排序,并且在您收到 View 准备就绪的通知时不能应用排序。您唯一能做的就是等到组件初始化生命周期结束。您可以使用 setTimeout() 来做到这一点。

我不认为没有 setTimeout() 就可以解决这两个问题,所以在这种情况下,无论您是从 OnInit 还是从 AfterViewInit 调用它都没有关系。

对您的代码的一些其他观察:

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

this.dataSource.data = myData;

这使您不必在之后将呈现的数据连接到数据源,因此您可以在初始化数据源时第一次执行此操作:

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

关于javascript - 如果没有 setTimeOut,MatSort 和 MatPaginator 将无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53013602/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com