Skip to content

fix(ChangeDetection): ngAfterViewChecked is called when ChangeDetector is detached #7054

@0x-r4bbit

Description

@0x-r4bbit

When detaching a change detector from the change detector tree, it should not cause the component to call ngAfterViewChecked or ngDoCheck. However, it seems those are called, while change detection itself is not performed.

Here's a plunk that illustrates the issue: http://plnkr.co/edit/px2oAkjzElRy3iqgP6jr?p=preview

I'll explain really quick what it does:

It's a single component that is bootstrapped and it detaches the change detector from the change detector tree:

  ngOnInit() {
    this.cd.detach();
  }

Whenever ngAfterViewChecked is called, I want to add a class to the component's host element so I can visualize that change detection has been performed. The class is then removed after 2 seconds. In order to make sure that setTimeout() doesn't trigger infinite tick() calls, this happens outside Angular's zone:

  ngAfterViewChecked() {
    this.el.nativeElement.classList.add('checked');
    this.zone.runOutsideAngular(() => {
      setTimeout(() => {
        this.el.nativeElement.classList.remove('checked');
      }, 2000);
    })
  }

Expectation: When bootstrapping the app, or clicking "Trigger CD", the app component shouldn't turn green. But it does. Although, we can see that CD itself is not performed, as the binding of the component is not reflected in the DOM

UPDATE:

The exact same happens to ngDoCheck() callback. Even though CD is detached, ngDoCheck() is called. Here's a punk that demonstrates it (pretty much the same thing, just that it turns red): http://plnkr.co/edit/HNRYZVdly2QG4MLHm64a?p=preview

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions