如何通过自定义指令动态添加组件

c19*_*992 8 angular

我想编写一个自定义指令,它将根据 div 内的某些逻辑动态添加组件,我在其中使用了自定义指令。

我尝试使用 componentFactoryResolver 和 viewContainerRef.createComponent 动态添加组件

<div myDirective> 
   <!-- dynamically add component through directive -->
   <span>Hello</span> 
</div>

// my custom directive

myDirective {
    constructor( private element: ElementRef,
        private renderer: Renderer,
        private viewContainerRef: ViewContainerRef,
        private componentFactoryResolver: ComponentFactoryResolver
    ) { }

    ngOnInit() {
        let componentFactory = this.componentFactoryResolver
                    .resolveComponentFactory(myComponent);
        let componentRef = this.viewContainerRef
                    .createComponent(componentFactory, 0);
    }

}
Run Code Online (Sandbox Code Playgroud)

实际结果:组件在 div 之后创建,预期:组件应添加到 div 内

yur*_*zui 11

将动态创建的组件放置在宿主元素旁边是有历史原因的。

但是您可以通过将创建的元素移动到宿主元素内来更改此行为。

@Directive({
  selector: '[myDirective]'
})
export class MyDirective {
  constructor(private element: ElementRef,
    private viewContainerRef: ViewContainerRef,
    private componentFactoryResolver: ComponentFactoryResolver
  ) { }

  ngOnInit() {
    const componentFactory = this.componentFactoryResolver
      .resolveComponentFactory(DynamicComponent);

    const componentRef = this.viewContainerRef.createComponent(componentFactory);

    const host = this.element.nativeElement;
    host.insertBefore(componentRef.location.nativeElement, host.firstChild)
  }
} 
Run Code Online (Sandbox Code Playgroud)

NG 运行示例

  • 考虑到 @jarodsmk 的评论,我能够使用这种方法,同时简单地省略“componentFactory”步骤。所以对`createComponent`的调用变成了`createComponent(DynamicComponent)` (3认同)
  • 值得一提的是,组件工厂解析器(以及一般的组件工厂)在最近的 Ng 版本中已被弃用 https://angular.io/api/core/ComponentFactoryResolver (2认同)

Mia*_*ovA 2

你可以使用 ng-template 来实现:

<div> 
<ng-template myDirective>
   <!-- dynamically add component through directive -->
</ng-template>
   <span>Hello</span> 
</div>
Run Code Online (Sandbox Code Playgroud)

检查我刚刚在Stackblitz上创建的这个示例。

希望这有效!

注意:如果您想延迟加载和动态加载组件,请检查ng-conf中的Manfred Steyer演示文稿

更新:我在指令中添加了一些逻辑。另外,我不明白为什么你不想添加 ng-template。