Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 OnPush change detection for dynamic components

I have an Angular component that dynamically creates various other types of component inside itself. It binds its own properties to child component @Input properties via an OnChanges hook.

This binding works fine when the child component's change detection is set to Default. Then the new inputs are detected and the component template is updated.

However, it doesn't work when change detection is OnPush, then the change is not detected. I believe the change should be detected because a new immutable object, a string, is assigned to a component @Input property.

Here's a plunker to demonstrate: https://plnkr.co/edit/0wHQghtww2HXVbC27bC1

How can I get this parent-to-dynamic-child property binding to work with ChangeDetectionStrategy.OnPush?

like image 505
Chris Fulstow Avatar asked Jan 23 '17 00:01

Chris Fulstow


1 Answers

As possible workaround for OnPush component would be using setter together with cdRef.markForCheck():

change-detection-onpush.component.ts

@Component({
  selector: 'app-change-detection-onpush',
  template: `
    <div>
      ChangeDetectionStrategy.OnPush: {{ message || '[blank]' }}
    </div>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChangeDetectionOnPushComponent implements IMyComponent {
  private _message: string;

  constructor(private cdRef: ChangeDetectorRef) {}

  set message(val: string) {
    this.cdRef.markForCheck();
    this._message = val;
  }

  get message() {
    return this._message;
  }
}

Modified Plunker

like image 112
yurzui Avatar answered Sep 24 '22 13:09

yurzui