使用Akita Entity Store时Angular Material Datatable Paginator返回undefined
问题原因
你代码里的MatPaginator和MatSort都被放在了依赖异步数据的*ngIf条件渲染块内,ngAfterViewInit触发时HTTP请求还未返回,模板中的分页器和排序组件尚未渲染到DOM,因此ViewChild查询结果为undefined。
解决方案
以下三种方案均可解决问题,按需选择即可:
方案1:使用setter形式的ViewChild(最推荐)
当目标组件被渲染到DOM时,setter会自动触发,无需关心渲染时机:
// customers.component.ts private _paginator: MatPaginator; private _sort: MatSort; // 替换原来的ViewChild声明 @ViewChild(MatPaginator) set paginator(instance: MatPaginator) { if (instance) { this._paginator = instance; this.initTableControls(); } } @ViewChild(MatSort) set sort(instance: MatSort) { if (instance) { this._sort = instance; this.initTableControls(); } } // 封装你原来要在ngAfterViewInit里执行的逻辑 private initTableControls(): void { if (this._sort && this._paginator) { // 此处写入你原本的业务逻辑 } }
方案2:修改渲染逻辑避免条件移除DOM
将分页器移到*ngIf外,用hidden属性控制显隐,保证组件初始化时就会渲染到DOM:
<!-- customer.component.html --> <ng-container *ngIf="(customers$ | async) as customers"> <ng-container *ngIf="customers.length > 0; else noCustomers"> <!-- 表格代码保留 --> </ng-container> <!-- 分页器移到外层,无数据时隐藏而非移除 --> <mat-paginator [hidden]="customers.length === 0"> <!-- 分页器配置保留 --> </mat-paginator> </ng-container> <ng-template #noCustomers><p>No Customers</p></ng-template>
修改后原ngAfterViewInit内的逻辑即可正常执行。
方案3:手动监听数据变化后查询
在数据返回后手动触发变更检测,再获取组件实例:
// customers.component.ts import { ChangeDetectorRef } from '@angular/core'; export class IndexComponent implements OnInit, AfterViewInit, OnDestroy { constructor( // 其他注入保留 private cdr: ChangeDetectorRef ) {} ngOnInit(): void { this.customers$ = this._customersQuery.customers$.pipe( tap(customers => { if (customers.length > 0) { // 手动触发变更检测,更新DOM后即可拿到组件实例 this.cdr.detectChanges(); if (this._sort && this._paginator) { // 此处写入你原本的业务逻辑 } } }) ); this.customerService.get().subscribe(); } }
内容的提问来源于stack exchange,提问作者realnsleo
相关产品推荐
相关产品推荐

