-
-
Save caroso1222/1c99aee8c9efe873902a9c590ab7b40a to your computer and use it in GitHub Desktop.
import { | |
Injectable, | |
Injector, | |
ComponentFactoryResolver, | |
EmbeddedViewRef, | |
ApplicationRef | |
} from '@angular/core'; | |
@Injectable() | |
export class DomService { | |
constructor( | |
private componentFactoryResolver: ComponentFactoryResolver, | |
private appRef: ApplicationRef, | |
private injector: Injector | |
) { } | |
appendComponentToBody(component: any) { | |
// 1. Create a component reference from the component | |
const componentRef = this.componentFactoryResolver | |
.resolveComponentFactory(component) | |
.create(this.injector); | |
// 2. Attach component to the appRef so that it's inside the ng component tree | |
this.appRef.attachView(componentRef.hostView); | |
// 3. Get DOM element from component | |
const domElem = (componentRef.hostView as EmbeddedViewRef<any>) | |
.rootNodes[0] as HTMLElement; | |
// 4. Append DOM element to the body | |
document.body.appendChild(domElem); | |
// 5. Wait some time and remove it from the component tree and from the DOM | |
setTimeout(() => { | |
this.appRef.detachView(componentRef.hostView); | |
componentRef.destroy(); | |
}, 3000); | |
} | |
} |
This gist is part of this tutorial: https://medium.com/hackernoon/angular-pro-tip-how-to-dynamically-create-components-in-body-ba200cc289e6. You'll see the instructions on how to use this service over there.
Great code! I made some small modifications to allow for initializing component properties and appending to any html element!
https://gist.github.com/reed-lawrence/1f6b7c328ad3886e60dc2b0adcf75a97
I did it and it work well,
but that does not include the styleUrls - css files.
how can I include them?
It works perfectly the first time!
Thank you very much for the contribution.
I guess you can use this instead
const domElem = componentRef.location.nativeElement;
Angular sucks
Verry usefull!
It also works in Angular 14 with small adjustments, I used your ideas after a lot of searching.
If it helps someone:
In constructor:
viewContainerRef.clear();
this.daterangepickerRef = this.viewContainerRef.createComponent(NgxDaterangepickerBootstrapComponent, {injector: this.injector});
this.daterangepickerElement = (this.daterangepickerRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
document.body.appendChild(this.daterangepickerElement); // add daterangepickerElement to DOM body, to fix position top left issues
this.daterangepicker = (<NgxDaterangepickerBootstrapComponent>this.daterangepickerRef.instance);
this.daterangepicker.inline = false; // set inline to false for all directive usage
and in ngOnDestroy:
const reflectComponent = reflectComponentType(NgxDaterangepickerBootstrapComponent);
const selector = document.querySelector(reflectComponent!.selector);
if (selector !== null) document.body.removeChild(selector);
this.applicationRef.detachView(this.daterangepickerRef.hostView);
this.daterangepickerRef.destroy();
Thank you!
how to use this service?