I have been reading the Dynamic component loading for Angular section, provided in the link below, Seeming highly complex and confusing my small brain, hard to understand all the syntax and names.
https://angular.io/guide/dynamic-component-loader
My question is what does @ViewChild do? the angular documentation states:
Property decorator that configures a view query.
But this doesn't give any understanding of what it does "what is a view query, what does that mean"? or why we are using it.
I later googled what is a view query which gave:
A view query is a requested reference to a child element within a component view which contains metadata of the element
But again I don't know really why or what this is doing for me in the code that follows that is shown in the above url.
Maybe this section should be after directives as I must be missing something.
when it calls this in the loadComponent() function, the adHost is a Directive that seems to be empty(no code in it) if you look at the below code, what is viewContainerRef, is ViewContainerRef my actual child component?
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
Does anyone know of any sites with simple and understandable uses for this?
The ad-banner.component.ts looks like this:
import { Component, OnInit, OnDestroy, Input, ViewChild, ComponentFactoryResolver} from '@angular/core';
import { AdItem } from '../ad-item';
import { AdDirective } from '../ad.directive';
import { AdComponent } from '../AdComponent';
@Component({
selector: 'app-ad-banner',
templateUrl: './ad-banner.component.html'
})
export class AdBannerComponent implements OnInit, OnDestroy {
@Input() ads: AdItem[] = [];
currentAdIndex = -1;
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
interval: any;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit(): void {
this.loadComponent();
this.getAds();
}
ngOnDestroy(): void {
clearInterval(this.interval);
}
loadComponent() {
this.currentAdIndex =(this.currentAdIndex + 1) % this.ads.length;
const adItem = this.ads[this.currentAdIndex];
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
componentRef.instance.data = adItem.data;
}
getAds() {
this.interval = setInterval(() => {
this.loadComponent();
}, 3000);
}
}
The add-banner.comoponent.html looks like this:
<div class="add-banner-example">
<h3>Advertisements</h3>
<ng-template adHost></ng-template>
</div>
The ad.directive.ts looks like this:
import { Directive, ViewContainerRef } from "@angular/core";
@Directive({
selector: '[adHost]'
})
export class AdDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}