【问题标题】:Understanding change detection in angular 2了解角度 2 中的变化检测
【发布时间】:2017-03-23 17:17:16
【问题描述】:

我在 Angular 2 文档中遇到过以下示例

@Component({
  selector: 'cmp',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `Number of ticks: {{numberOfTicks}}`
})
class Cmp {
  numberOfTicks = 0;
  constructor(ref: ChangeDetectorRef) {
    setInterval(() => {
      this.numberOfTicks ++
     // the following is required, otherwise the view will not be updated
     this.ref.markForCheck();
    }, 1000);
  }
}

如上所述,当 changeDetection 为 ChangeDetectionStrategy.OnPush 时,视图仅在“this.ref.markForCheck();”时更新被调用。

谁能在这里解释一下markForCheck()方法的重要性。

【问题讨论】:

  • 对于上述组件,我还添加了一个带有点击事件处理程序的按钮, 我的期望是,当用户单击按钮,将进行更改检测,并且视图将更新为最新的 numberOfTicks,但即使是现在,也只有在 test() 函数中调用 markForCheck 时才会更新视图。希望我的问题有意义..

标签: angular


【解决方案1】:

使用ChangeDetectionStrategy.OnPush Angular 运行更改检测,当@Input() 更新时,接收到 Angular 侦听的 DOM 事件,或者异步管道 (| async) 接收到新值。

例如,如果您从服务订阅 observable 并更新组件的状态,则不会更新与此状态的绑定,因为上述列表未涵盖此内容。如果你打电话给this.ref.markForCheck(),你告诉 Angular 它应该运行更改检测,因为实际上存在需要更新的更改(这也是异步管道所做的)。

其他情况是,如果您明确地 (this.zone.runOutsideAngular()) 或由于某些其他原因在 Angulars 区域之外运行的代码修改了组件的状态,这也不会被覆盖(即使代码是事件处理程序)。

【讨论】:

  • 对于上述组件,我还添加了一个带有点击事件处理程序的按钮, 我的期望是,当用户单击按钮,将发生变化检测,并且视图将更新为最新的 numberOfTicks,但即使是现在,也只有在 test() 函数中调用 markForCheck 时才会更新视图。希望我的问题有意义..
  • 我确信事件绑定会导致更改检测运行。你能创建一个 Plunker 来复制和调查吗?另见stackoverflow.com/questions/35386822/…
  • 很高兴听到,开始担心了 ;-)
【解决方案2】:

使用ChangeDetectionStrategy.OnPush 告诉 Angular 不要对您的组件执行更改检测(即更新其视图),除非组件的一个或多个输入发生更改(这些输入应该是不可变对象)。

对于来自组件本身并需要更新视图的任何事件,您必须明确告诉更改检测器在下一次更改检测运行时查找该组件中的更改。

在这个 sn-p 中,ref 是对变化检测器的引用。调用 ref.markForCheck() 会告诉变化检测器发生了一些会改变视图的事情(即 numberOfTicks 已增加)并且它需要重新计算它。

【讨论】:

    猜你喜欢
    • 2018-06-23
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2018-10-24
    • 1970-01-01
    • 2018-05-07
    • 2017-03-12
    相关资源
    最近更新 更多