ChangeDetectorRef

Angular 各种视图的基础类,提供变更检测功能。 变更检测树会收集要检查的所有视图。 使用这些方法从树中添加或移除视图、初始化变更检测并显式地把这些视图标记为脏的,意思是它们变了、需要重新渲染。

Base class for Angular Views, provides change detection functionality. A change-detection tree collects all views that are to be checked for changes. Use the methods to add and remove views from the tree, initiate change-detection, and explicitly mark views as dirty, meaning that they have changed and need to be rerendered.

      
      abstract class ChangeDetectorRef {
  abstract markForCheck(): void
  abstract detach(): void
  abstract detectChanges(): void
  abstract checkNoChanges(): void
  abstract reattach(): void
}
    

方法

当视图使用 OnPushcheckOnce)变更检测策略时,把该视图显式标记为已更改,以便它再次进行检查。

When a view uses the OnPush (checkOnce) change detection strategy, explicitly marks the view as changed so that it can be checked again.

abstract markForCheck(): void
      
      abstract markForCheck(): void
    
参数

没有参数。

返回值

void

当输入已更改或视图中发生了事件时,组件通常会标记为脏的(需要重新渲染)。调用此方法会确保即使那些触发器没有被触发,也仍然检查该组件。

Components are normally marked as dirty (in need of rerendering) when inputs have changed or events have fired in the view. Call this method to ensure that a component is checked even if these triggers have not occured.

从变更检测树中分离开视图。 已分离的视图在重新附加上去之前不会被检查。 与 detectChanges() 结合使用,可以实现局部变更检测。

Detaches this view from the change-detection tree. A detached view is not checked until it is reattached. Use in combination with detectChanges() to implement local change detection checks.

abstract detach(): void
      
      abstract detach(): void
    
参数

没有参数。

返回值

void

即使已分离的视图已标记为脏的,它们在重新附加上去之前也不会被检查。

Detached views are not checked during change detection runs until they are re-attached, even if they are marked as dirty.

检查该视图及其子视图。与 detach 结合使用可以实现局部变更检测。

Checks this view and its children. Use in combination with detach to implement local change detection checks.

abstract detectChanges(): void
      
      abstract detectChanges(): void
    
参数

没有参数。

返回值

void

检查变更检测器及其子检测器,如果检测到任何更改,则抛出异常。

Checks the change detector and its children, and throws if any changes are detected.

abstract checkNoChanges(): void
      
      abstract checkNoChanges(): void
    
参数

没有参数。

返回值

void

在开发模式下可用来验证正在运行的变更检测器是否引入了其它变更。

Use in development mode to verify that running change detection doesn't introduce other changes.

把以前分离开的视图重新附加到变更检测树上。 视图会被默认附加到这棵树上。

Re-attaches the previously detached view to the change detection tree. Views are attached to the tree by default.

abstract reattach(): void
      
      abstract reattach(): void
    
参数

没有参数。

返回值

void

使用说明

下面的例子演示了如何修改默认的变更检测行为,以便在需要时执行显式变更检测。

The following examples demonstrate how to modify default change-detection behavior to perform explicit detection when needed.

使用 markForCheck()CheckOnce 策略

Use markForCheck() with CheckOnce strategy

下面的例子为组件设置了 OnPush 变更检测策略(CheckOnce 而不是默认的 CheckAlways),然后每隔一段时间强制进行第二轮检测。 参见在线例子

The following example sets the OnPush change-detection strategy for a component (CheckOnce, rather than the default CheckAlways), then forces a second check after an interval. See live demo.

@Component({ selector: 'my-app', template: `Number of ticks: {{numberOfTicks}}`, changeDetection: ChangeDetectionStrategy.OnPush, }) class AppComponent { numberOfTicks = 0; constructor(private ref: ChangeDetectorRef) { setInterval(() => { this.numberOfTicks++; // require view to be updated this.ref.markForCheck(); }, 1000); } }
      
      
  1. @Component({
  2. selector: 'my-app',
  3. template: `Number of ticks: {{numberOfTicks}}`,
  4. changeDetection: ChangeDetectionStrategy.OnPush,
  5. })
  6.  
  7. class AppComponent {
  8. numberOfTicks = 0;
  9.  
  10. constructor(private ref: ChangeDetectorRef) {
  11. setInterval(() => {
  12. this.numberOfTicks++;
  13. // require view to be updated
  14. this.ref.markForCheck();
  15. }, 1000);
  16. }
  17. }

分离开变更检测器以限制变更检测的发生频度

Detach change detector to limit how often check occurs

下面的例子定义了一个带有只读数据的大型列表,这些数据预计每秒会变化很多次。 为了提高性能,我们检测和更新列表的频率就应该比实际发生的变化少得多。 要解决这个问题,就要分离开变更检测器,并每隔五秒钟显式执行一次变更检查。

The following example defines a component with a large list of read-only data that is expected to change constantly, many times per second. To improve performance, we want to check and update the list less often than the changes actually occur. To do that, we detach the component's change detector and perform an explicit local check every five seconds.

class DataListProvider { // in a real application the returned data will be different every time get data() { return [1, 2, 3, 4, 5]; } } @Component({ selector: 'giant-list', template: ` <li *ngFor="let d of dataProvider.data">Data {{d}}</li> `, }) class GiantList { constructor(private ref: ChangeDetectorRef, private dataProvider: DataListProvider) { ref.detach(); setInterval(() => { this.ref.detectChanges(); }, 5000); } } @Component({ selector: 'app', providers: [DataListProvider], template: ` <giant-list><giant-list> `, }) class App { }
      
      
  1. class DataListProvider {
  2. // in a real application the returned data will be different every time
  3. get data() { return [1, 2, 3, 4, 5]; }
  4. }
  5.  
  6. @Component({
  7. selector: 'giant-list',
  8. template: `
  9. <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
  10. `,
  11. })
  12. class GiantList {
  13. constructor(private ref: ChangeDetectorRef, private dataProvider: DataListProvider) {
  14. ref.detach();
  15. setInterval(() => { this.ref.detectChanges(); }, 5000);
  16. }
  17. }
  18.  
  19. @Component({
  20. selector: 'app',
  21. providers: [DataListProvider],
  22. template: `
  23. <giant-list><giant-list>
  24. `,
  25. })
  26. class App {
  27. }

重新附加一个已分离的组件

Reattaching a detached component

下面的例子创建了一个用来显示活动数据的组件。 当 live 属性为 false 时,该组件就把它的变更检测器从主变更检测器树中分离出来,当该属性变为 true 时,则重新附加上它。

The following example creates a component displaying live data. The component detaches its change detector from the main change detector tree when the live property is set to false, and reattaches it when the property becomes true.

class DataProvider { data = 1; constructor() { setInterval(() => { this.data = 2; }, 500); } } @Component({selector: 'live-data', inputs: ['live'], template: 'Data: {{dataProvider.data}}'}) class LiveData { constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {} set live(value: boolean) { if (value) { this.ref.reattach(); } else { this.ref.detach(); } } } @Component({ selector: 'app', providers: [DataProvider], template: ` Live Update: <input type="checkbox" [(ngModel)]="live"> <live-data [live]="live"><live-data> `, }) class App1 { live = true; }
      
      
  1. class DataProvider {
  2. data = 1;
  3. constructor() {
  4. setInterval(() => { this.data = 2; }, 500);
  5. }
  6. }
  7.  
  8.  
  9. @Component({selector: 'live-data', inputs: ['live'], template: 'Data: {{dataProvider.data}}'})
  10. class LiveData {
  11. constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
  12.  
  13. set live(value: boolean) {
  14. if (value) {
  15. this.ref.reattach();
  16. } else {
  17. this.ref.detach();
  18. }
  19. }
  20. }
  21.  
  22. @Component({
  23. selector: 'app',
  24. providers: [DataProvider],
  25. template: `
  26. Live Update: <input type="checkbox" [(ngModel)]="live">
  27. <live-data [live]="live"><live-data>
  28. `,
  29. })
  30.  
  31. class App1 {
  32. live = true;
  33. }