如何在指定位置以编程方式注入组件<ng-template>?



如何以编程方式实例化组件并将其插入模板中的指定位置?

堆栈闪电战: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);
}
}

堆叠闪电战:https://stackblitz.com/edit/angular-dzx7vz

但是,我收到错误:

错误:无法读取未定义的属性"创建组件">

我正在使用Angular编写窗口管理器。是否可以将组件注入窗口模板的指定位置,然后将窗口插入主容器?我想保留对每个窗口的引用,以便能够进一步删除它。

您必须为此进行三个主要更改。

  1. 需要编写一个主机指令来托管您的动态 此处解释的组件 - https://angular.io/guide/dynamic-component-loader

  2. 使用

    @ViewChild(HostDirective, {static: false}) hostDirective;

  3. 将组件加载延迟到下一次更改检测 - 使用setTimeout

你可以参考这个堆栈闪电战 https://stackblitz.com/edit/angular-kbjr75

相关内容

  • 没有找到相关文章

最新更新