1

Current code works but is surely far from ideal (I mean probably not the Angular way).

My component may or may not project external content. The div wrapper where the projected content will land is rendered only when one of the component's Inputs is not undefined. A setTimeout call occures within the former Input's setter to postpone some DOM content inspection, telling if a specific class should be applied or not, changeDetectorRef.markForCheck() ultimately triggers the view update accordingly.

Could someone guide me on what should be done instead?

@Component({
    // Almost the whole the application uses OnPush change detection strategy
    changeDetection: ChangeDetectionStrategy.OnPush,
    template: `
    <!-- … -->
    <div #footer *ngIf="parameters"> <!-- the wrapper -->
      <ng-content select="'.external-buttons"></ng-content> <!-- injected content -->
    </div>
    `
})
export class cardComponent {
    @HostBinding('class.hasInjectedButtons') hasInjectedButtons: boolean;
    @ViewChild('footer') footer: ElementRef;

    @Input() set data(payload: wsDataScheme) {
        // …
        // Attempt to check whether the CSS class should be applied
        setTimeout(() => {
            this.hasInjectedButtons = this.footer
                ? this.footer.nativeElement.querySelector('.external-buttons') 
                : false
            ;
            this.changeDetectorRef.markForCheck();
        });
    }
}

I feel confused about Angular lifecycle resolution process dispite having read few articles using graphs like the one down below. I expected the "footer" ViewChild to be populated and accessible when the ngAfterViewCheck gets executed but it seems it's not. Playing around with lifecycle hook ngAfterContentCheck and ngOnChanges did not helped me either, nor ContentChild projected content reference decorator.

Angular lifecycle hooks order

Stphane
  • 3,368
  • 5
  • 32
  • 47
  • Im not sure I understand what you are trying to do but If you want to figure out if the ng-content is in the DOM, use a viewchild setter which will be triggered as soon as it exists. – ukn Apr 12 '19 at 17:29
  • There is a difference between _view DOM_ and _content DOM_, view DOM gives access to elements declared within the component template itself whereas the _content DOM_ refers to "projected" elements, (elements belonging to/declared into a upper component in the tree) and which happens to be rendered in the former component. `project-text`) – Stphane Apr 13 '19 at 08:53

0 Answers0