Angular 理解角度2的变化检测

Angular 理解角度2的变化检测,angular,Angular,我在Angular 2文档中遇到了以下示例 @Component({ selector: 'cmp', changeDetection: ChangeDetectionStrategy.OnPush, template: `Number of ticks: {{numberOfTicks}}` }) class Cmp { numberOfTicks = 0; constructor(ref: ChangeDetectorRef) { setInterval(() =

我在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()方法的重要性。

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

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


在此代码段中,
ref
是对变更检测器的引用。调用
ref.markForCheck()
告诉更改检测器发生了将更改视图的事情(即
numberOfTicks
已增加),它需要重新计算。

使用
ChangeDetectionStrategy.OnPush
角度运行更改检测,当在
@Input()
中更新时,接收到DOM事件,或者异步管道(
|async
)接收到新值

例如,如果您订阅了一个来自服务的可观察对象并更新了组件的状态,那么到此状态的绑定将不会被更新,因为上面的列表中没有涉及到这一点。如果调用
this.ref.markForCheck()
,您会告诉Angular它应该运行更改检测,因为实际上存在需要更新的更改(异步管道也是这样做的)


其他情况是,如果您显式(
this.zone.runOutsideAngular()
)或出于某些其他原因,在Angulars zone之外运行的代码修改组件的状态,这也将不包括在内(即使代码是事件处理程序)。

对于上面的组件,我还添加了一个带有click事件处理程序的按钮,按钮我的期望是,当用户单击该按钮时,将发生更改检测,并使用最新的numberOfTicks更新视图,但即使是现在,视图也只有在test()函数中调用markForCheck时才会更新。希望我的问题有意义。对于上面的组件,我还添加了一个带有click事件处理程序的按钮,按钮我的期望是,当用户单击按钮时,将发生更改检测,并且视图将使用最新的numberOfTicks更新,但即使现在,视图也仅在test()函数中调用markForCheck时更新。希望我的问题有意义。我确信事件绑定会导致更改检测运行。你能创建一个Plunker来复制和调查吗?看到也很高兴听到,开始担心起来;-)