首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular12 OnPush变化检测策略

Angular12 OnPush变化检测策略
EN

Stack Overflow用户
提问于 2022-04-08 06:09:57
回答 1查看 393关注 0票数 1

我有一个运行良好的角度代码,但我仍然没有具体了解变化检测是如何工作的。

以下组件使用材料设计显示表,并实现表分页。我做了以下步骤:

changeDetection

  • 将设置为OnPush模式,3秒后,
  1. 从模板中获得了页面器的引用,在setTimeout中获得了MatTableDataSource在ngAfterViewInit中的引用。

初始页面加载后的结果是,表分页器在3秒后工作良好,页面被正确地重新呈现。

这与以下事实相矛盾:在OnPush模式下,setTimeout不应该触发更改检测,并且我不会更改任何输入属性的引用。有什么想法吗?

代码语言:javascript
复制
@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);
}
代码语言:javascript
复制
enter code here
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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

代码语言:javascript
复制
// 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

代码语言:javascript
复制
// 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,

然后看一下模板:

代码语言:javascript
复制
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,看起来他们使用指令来呈现多个组件,其中任何一个都可能触发更改检测。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71792356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档