我有一些 DIV 可能标有指令
special
。该指令具有一定的有效逻辑。现在,我想在配备该指令的 DIV 中添加一个组件。
<div special ...>Monkey</div>
<div regular ...>Donkey</div>
按照Using ViewContainerRef
上的文档(由 this answer 针对类似问题建议),我在指令中运行以下命令。
@Directive({ selector: "[special]" })
export class SpecialDirective {
private viewRef = inject(ViewContainerRef); ...
constructor() {
const icon = this.viewRef.createComponent(IconComponent);
}
它的工作方式与文档中描述的一样:创建的图标(对应于
LeafContent
)被放置在 DOM 中标记为特殊的 DIV 后面(对应于
InnerItem
)。这正是我的问题:我希望图标成为受指令控制的 DIV 内部 HTML 的一部分。由于与其逻辑相关的各种原因,我无法将该指令向内移动。我尝试访问 viewRef.element
并检查了它的其他字段和方法。无济于事。在创建上设置索引没有帮助。我得到的最接近的是从文档中
分离/插入,但它只能让我管理元素的顺序之后我的DIV,而不是在其中它。 我已经看到了这个答案
,但它对我的情况没有帮助,因为更改是在用户单击 DIV 之后发生的,通过它已被创建并放置在视图中。 如何更改
viewRef
实例的内部?最理想的是,除了修改图标之外,我还想删除其中的一些标签。
template reference variable
#insertHere
来明确指定插入新组件的位置,我们可以使用 viewChild
并指定 read
属性来获取具有 ViewContainerRef
方法的 createComponent
@Component({
selector: 'inner-item',
template: `
<button (click)="loadContent()">Load content</button>
<ng-container #insertHere></ng-container>
`,
})
export class InnerItem {
insertHere = viewChild('insertHere', {
read: ViewContainerRef,
});
loadContent() {
this.insertHere()?.createComponent(LeafContent);
}
}
完整代码:
import { Component, viewChild, ViewContainerRef } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'leaf-content',
template: `
This is the leaf content
`,
})
export class LeafContent {}
@Component({
selector: 'inner-item',
template: `
<button (click)="loadContent()">Load content</button>
<ng-container #insertHere></ng-container>
`,
})
export class InnerItem {
insertHere = viewChild('insertHere', {
read: ViewContainerRef,
});
loadContent() {
this.insertHere()?.createComponent(LeafContent);
}
}
@Component({
selector: 'outer-container',
imports: [InnerItem],
template: `
<p>This is the start of the outer container</p>
<inner-item />
<p>This is the end of the outer container</p>
`,
})
export class OuterContainer {}
@Component({
selector: 'app-root',
imports: [OuterContainer],
template: `
<outer-container/>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App);