Dynamic Components
-
Dynamic Components
-
The function allows creating a
ComponentRefinstance based on providedComponentand a set of options:
import { ApplicationRef, createComponent, EnvironmentInjector } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ToastService {
constructor(
private appRef: ApplicationRef,
private injector: EnvironmentInjector
) { }
open(text: string) {
// Create a `ComponentRef` instance.
const dialogRef = createComponent(ToastComponent, {
environmentInjector: this.injector
});
dialogRef.setInput('text', text);
document.body.appendChild(dialogRef.location.nativeElement);
// Register the newly created ref using the `ApplicationRef` instance
// to include the component view into change detection cycles.
this.appRef.attachView(dialogRef.hostView);
}
}
- It’s possible to pass a new environment injector inherited from the current one:
export class ToastService {
constructor(
private appRef: ApplicationRef,
private injector: EnvironmentInjector
) { }
open(text: string) {
const newEnvInjector = createEnvironmentInjector([
{
provide: 'MyToken',
useValue: 'Token'
}
], this.injector);
const dialogRef = createComponent(ToastComponent, {
environmentInjector: newEnvInjector
});
dialogRef.setInput('text', text);
document.body.appendChild(dialogRef.location.nativeElement);
this.appRef.attachView(dialogRef.hostView);
}
}
- It’s possible to pass an element injector:
export class ToastService {
constructor(
private appRef: ApplicationRef,
private injector: EnvironmentInjector
) { }
open(text: string) {
const elementInjector = Injector.create({
providers: [
{
provide: 'MyToken',
useValue: 'Token'
}
],
});
const dialogRef = createComponent(ToastComponent, {
environmentInjector: this.injector,
elementInjector
});
dialogRef.setInput('text', text);
document.body.appendChild(dialogRef.location.nativeElement);
this.appRef.attachView(dialogRef.hostView);
}
}
- The component can be appended to a
hostelement:
export class ToastService {
constructor(
private appRef: ApplicationRef,
private injector: EnvironmentInjector
) { }
open(text: string) {
const dialogRef = createComponent(ToastComponent, {
environmentInjector: this.injector,
hostElement: document.getElementById('toasts-container')!
});
dialogRef.setInput('text', text);
this.appRef.attachView(dialogRef.hostView);
}
}
- We can pass
projectableNodes— A list of DOM nodes that should be projected through of the new component instance:
openDialog<T>(dialogContent: Type<T>) {
const footer = document.createElement('p');
footer.innerText = 'footer';
const dialogContentRef = createComponent(dialogContent, {
environmentInjector: this.injector
})
const dialogRef = createComponent(DialogComponent, {
environmentInjector: this.injector,
hostElement: document.getElementById('dialog-container')!,
projectableNodes: [
// ng-content nodes
[dialogContentRef.location.nativeElement],
// second ng-content (e.g <ng-content select="footer"></ng-content>)
[ footer ]
]
})
this.appRef.attachView(dialogRef.hostView)
}