使用指令将组件动态添加到子元素

Posted

技术标签:

【中文标题】使用指令将组件动态添加到子元素【英文标题】:Add a component dynamically to a child element using a directive 【发布时间】:2017-07-24 16:51:10 【问题描述】:

尝试使用指令将组件动态放置到子元素。

组件(作为模板):

@Component(
  selector: 'ps-tooltip',
  template: `
    <div class="ps-tooltip">
      <div class="ps-tooltip-content">
        <span>content</span>
      </div>
    </div>
  `
)
export class TooltipComponent 

  @Input()
  content: string;


指令:

import  TooltipComponent  from './tooltip.component';

@Directive(
  selector: '[ps-tooltip]',
)
export class TooltipDirective implements AfterViewInit 

  @Input('ps-tooltip') content: string;

  private tooltip: ComponentRef<TooltipComponent>;

  constructor(
      private viewContainerRef: ViewContainerRef,
      private resolver: ComponentFactoryResolver,
      private elRef: ElementRef,
      private renderer: Renderer
  )  

  ngAfterViewInit() 
    // add trigger class to el
    this.renderer.setElementClass(this.elRef.nativeElement, 'ps-tooltip-trigger', true); // ok

    // factory comp resolver
    let factory = this.resolver.resolveComponentFactory(TooltipComponent);

    // create component
    this.tooltip = this.viewContainerRef.createComponent(factory);
    console.log(this.tooltip);

    // set content of the component
    this.tooltip.instance.content = this.content as string;
  

问题是这是在创建一个兄弟姐妹,我想要一个孩子(见下文)

结果:

<a class="ps-btn ps-tooltip-trigger" ng-reflect-content="the tooltip">
  <span>Button</span>
</a>
<ps-tooltip>...</ps-tooltip>

想要的结果:

<a class="ps-btn ps-tooltip-trigger" ng-reflect-content="the tooltip">
  <span>Button</span>
  <ps-tooltip>...</ps-tooltip>
</a>

提前感谢您的帮助!

【问题讨论】:

没有办法做到这一点。您需要一个子组件的ViewContainerRef,其中添加的组件可以是其兄弟姐妹。这就是ViewContainerRef.createComponent() 的工作原理。 感谢您的回答。我能问一下你建议什么来得到想要的结果吗?! 【参考方案1】:

即使动态组件作为子元素插入,您仍然可以使用以下方法将元素移动到所需位置:

this.elRef.nativeElement.appendChild(this.tooltip.location.nativeElement);

Plunker Example

【讨论】:

你绝对的英雄!【参考方案2】:

更好的方法是在其上使用带有模板引用变量的嵌套ng-template,以便将组件作为兄弟添加到ng-template,但现在是ng-template 的父级的子级。

你的模板应该是

<div class="ps-tooltip">
  <div class="ps-tooltip-content">
    <span>content</span>
    <ng-template #addHere></ng-template>
  </div>
</div>

在你的组件中

@ViewChild('addHere') addHere: ViewContainerRef;

ngAfterViewInit() 
    ...

    this.tooltip = addHere.createComponent(factory)

    ...

【讨论】:

以上是关于使用指令将组件动态添加到子元素的主要内容,如果未能解决你的问题,请参考以下文章

Angular使用总结 --- 通过指令动态添加组件

Angular 2:向动态创建的组件添加指令

vue如何动态添加多个li

如何在 AngularJS 中动态添加指令?

如何在 AngularJS 中动态添加指令?

将动态插槽从父级传递到子级到孙子级