I dynamically create an Angular component like this (code is simplified, there are some missing parts):
[...]
@ViewChild(MyDirective, { static: true }) myHost!: MyDirective;
constructor(
private readonly compiler: Compiler,
private readonly injector: Injector,
) {}
[...]
const myModule: typeof MyModule = (
await import('../../../my/my.module')
).MyModule;
const moduleFactory: NgModuleFactory<MyModule> = await this.compiler.compileModuleAsync(
myModule,
);
const moduleReference: NgModuleRef<MyModule> = moduleFactory.create(this.injector);
const componentFactory: ComponentFactory<MyComponent> = moduleReference.instance.resolveComponent();
const componentReference: ComponentRef<MyComponent> = myHost.viewContainerReference.createComponent(
componentFactory,
undefined,
moduleReference.injector,
);
componentReference.instance.item = myItem;
componentReference.instance.options = myOptions;
// Here I need to wait ~200ms for the component to be available to request in the DOM ...
await timer(200).toPromise();
const myComponent: Element = document.querySelector('my-component');
// Then I use the component to generate an image with the library html-to-image
const dataUrl: string = await toSvg(myComponent);
return dataUrl;
I have to wait ~200ms for my component to be available in the DOM to request... otherwise it returns undefined. I have tried to implement ngAfterViewInit
in MyComponent
and then expose an observable so I can subscribe to it and THEN request it, but it stills returns undefined. MyComponent
only has @Inputs and a template, nothing else. The template looks something like this:
<ng-container *ngIf="condition; else loading">
<div prop="stuff | MyPipe">stuff</div>
</ng-container>
<ng-template #loading>
stuff
</ng-template>
How can I know when the dynamically created component is available to request?
I don't know if I have understood your code properly as there are some missing pieces. I think MyDirective is your anchor directive. And the answer below is based on those assumptions that I have made based on my understanding of your code base.
You should be using ComponentFactoryResolver.resolveComponentFactory() to resolve ComponentFactory for each of the components.
const componentFactory = this.componentFactoryResolver.resolveComponentFactory("give component name here");
const viewContainerRef = this.directiveName.viewContainerRef; //the directive should inject viewContainerRef to access the view container of the parent component which will host the dynamic components
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent<DynamicComponent>(componentFactory);
Read more about this here https://angular.io/guide/dynamic-component-loader
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.