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.