我有一个运行良好的角度代码,但我仍然没有具体了解变化检测是如何工作的。
以下组件使用材料设计显示表,并实现表分页。我做了以下步骤:
changeDetection
初始页面加载后的结果是,表分页器在3秒后工作良好,页面被正确地重新呈现。
这与以下事实相矛盾:在OnPush模式下,setTimeout不应该触发更改检测,并且我不会更改任何输入属性的引用。有什么想法吗?
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements OnInit, AfterViewInit {
dataSource: MatTableDataSource<IProduct> = new MatTableDataSource();
@ViewChild(MatPaginator) paginator!: MatPaginator;
displayedColumns: string[] = ['model', 'year', 'price'];
data: IProduct[] = [
{
model: 'Samsung-GT2',
year: 2022,
price: 120,
},
{
model: 'LG-X22',
year: 2021,
price: 99,
},
{
model: 'Philips-Q87',
year: 2019,
price: 69,
},
{
model: 'Huawei-SX1',
year: 2021,
price: 220,
},
];
constructor() {}
ngOnInit(): void {
this.dataSource.data = this.data;
}
ngAfterViewInit(): void {
setTimeout(() => {
this.dataSource.paginator = this.paginator;
}, 3000);
}enter code here发布于 2022-04-08 07:37:25
使用OnPush策略检测更改还有其他几个原因,可能是MatTable组件在更改paginator时触发了自身的更改检测。
从这里摘录的一句话:
https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/
当使用
检测器时,当它的任何输入属性发生变化、触发事件或可观察的触发事件时,框架将检查OnPush组件。
您必须查看mat表的源代码才能找到确切的原因,但正如您所看到的,很难控制对预先制作的组件的更改检测。
每个组件都有自己的变更检测器,将父组件设置为OnPush将阻止大多数更改检测渗透到该子组件,但它不会阻止子组件触发对自身的更改检测。
在源代码中,我们看到了以下说明:
https://github.com/angular/components/blob/master/src/material/table/table.ts
// See note on CdkTable for explanation on why this uses the default change detection strategy.
// tslint:disable-next-line:validate-decorators
changeDetection: ChangeDetectionStrategy.Default然后走到cdk桌子上:
https://github.com/angular/components/blob/master/src/cdk/table/table.ts
// The "OnPush" status for the `MatTable` component is effectively a noop, so we are removing it.
// The view for `MatTable` consists entirely of templates declared in other views. As they are
// declared elsewhere, they are checked when their declaration points are checked.
// tslint:disable-next-line:validate-decorators
changeDetection: ChangeDetectionStrategy.Default,然后看一下模板:
export const CDK_TABLE_TEMPLATE =
// Note that according to MDN, the `caption` element has to be projected as the **first**
// element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption
`
<ng-content select="caption"></ng-content>
<ng-content select="colgroup, col"></ng-content>
<ng-container headerRowOutlet></ng-container>
<ng-container rowOutlet></ng-container>
<ng-container noDataRowOutlet></ng-container>
<ng-container footerRowOutlet></ng-container>
`;Welp,看起来他们使用指令来呈现多个组件,其中任何一个都可能触发更改检测。
https://stackoverflow.com/questions/71792356
复制相似问题