Angular 使用组件包装主机内容的指令

Angular Directive that wraps host content with a component

我想知道如何编写以下场景:

app.component.html:

<div *appSlideOutDir>Hey there!</div>

指令代码是这样的:

export class SlideOutDirDirective implements OnInit {
  constructor(
    private viewContainer: ViewContainerRef,
    private templateRef: TemplateRef<any>
  ) {}

  ngOnInit() {
    const slideOutComponent =
      this.viewContainer.createComponent<SlideInComponent>(SlideInComponent);
    slideOutComponent.instance.viewContainer.clear();
    slideOutComponent.instance.viewContainer.createEmbeddedView(
      this.templateRef
    );
  }
}

SlideOutComponent 代码是这样的:

export class SlideInComponent {
  constructor(public viewContainer: ViewContainerRef) {}

它的模板是这样的:

<div [class.slide-in]="show">
  <ng-content></ng-content>
</div>

此 SlideOutComponent 最初用作组件,您可以将任何东西包裹起来并使其成为滑出式小吃店(如 material)类型的东西。但是,我想重用它并在指令中使用它来实现相同的目的...

但是,当前代码不会将 Hey there! 的原始内容注入到 SlideOutComponent 内部,而是作为兄弟组件紧挨着它:

<app-slide-in>...</app-slide-in>
<div>Hey there!</div>

如何获取带有指令的原始标记的 Hey there! 主体出现在 <app-slide-in> 中?

经过一番研究,我为您找到了答案。

更改您的 SlideOutComponent 以接受 templateRef 作为输入。

@Input() controlTemplate: TemplateRef<any>;

然后,在 HTML 中,将 ng-content 更改为:

<ng-container *ngTemplateOutlet="controlTemplate">
</ng-container>

最后,改变:

slideOutComponent.instance.viewContainer.createEmbeddedView(
  this.templateRef
);

至:

slideOutComponent.instance.controlTemplate = this.templateRef;

这种方法对我有用 - 我能够用标签包装任何组件。