Как создать экземпляр компонента программно и вставить его в указанное место в шаблоне?
Stackblitz: https://stackblitz.com/edit/angular-do71xk
import {Component, ComponentFactoryResolver, TemplateRef, ViewChild, ViewContainerRef, Type} from "@angular/core";
export interface PaneOptions {
component: Type<any>;
params?: any;
}
@Component({
selector: 'app-manager',
template: `
<ng-template #paneContainer></ng-template> <!-- probably redundant -->
<!-- window template -->
<ng-template #paneTemplate>
<div style="background: red">
<h3>Window header</h3>
<ng-template #paneBody></ng-template> <!-- or another ng-template -->
</div>
</ng-template>
`
})
export class ManagerComponent {
@ViewChild('paneContainer', {read: ViewContainerRef}) paneContainer: ViewContainerRef;
@ViewChild('paneTemplate', {read: ViewContainerRef}) paneTemplateRef: ViewContainerRef;
@ViewChild('paneTemplate', {read: TemplateRef}) paneTemplate: TemplateRef<any>;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
addPane(options: PaneOptions) {
// create embedded view of pane template
const embeddedView = this.paneContainer.createEmbeddedView(this.paneTemplate);
// resolve component and insert it into pane container
// instead, we need to clone #paneTemplate and insert component within <ng-content>
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(options.component);
const component = this.paneTemplateRef.createComponent(componentFactory);
Object.assign(component.instance, options.params);
}
}
И это другой подход, когда Я пытаюсь создать экземпляр компонента внутри внутреннего ng-шаблона.
import {Component, ComponentFactoryResolver, TemplateRef, ViewChild, ViewContainerRef, Type} from "@angular/core";
export interface PaneOptions {
component: Type<any>;
params?: any;
}
@Component({
selector: 'app-manager',
template: `
<ng-template #paneContainer></ng-template>
<!-- pane template -->
<ng-template #paneTemplate>
<div style="background: red">
<h3>Below within red area should be the inner component</h3>
<ng-template #inner></ng-template>
</div>
</ng-template>
`
})
export class ManagerComponent {
@ViewChild('paneContainer', {read: ViewContainerRef}) paneContainer: ViewContainerRef;
@ViewChild('inner', {read: ViewContainerRef}) innerTemplateRef: ViewContainerRef;
@ViewChild('paneTemplate', {read: TemplateRef}) paneTemplate: TemplateRef<any>;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
addPane(options: PaneOptions) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(options.component);
const component = this.innerTemplateRef.createComponent(componentFactory);
Object.assign(component.instance, options.params);
// create embedded view of pane template
const embeddedView = this.paneContainer.createEmbeddedView(this.paneTemplate);
}
}
Stackblitz: https://stackblitz.com/edit/angular-dzx7vz
Однако я получаю ошибку:
Ошибка: невозможно прочитать свойство 'createComponent' с неопределенным
Я пишу оконный менеджер, используя Angular. Можно ли внедрить компонент в указанное место шаблона окна, а затем вставить окно в основной контейнер? Я хочу сохранить ссылку на каждое окно, чтобы иметь возможность удалить его дальше.