Angular structural directive: wrap the host element with some another component

跟風遠走 提交于 2019-12-12 08:47:37

问题


I have simplest Angular structural directive:

import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[hello]' })
export class HelloDirective {
  constructor(
    private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {
      this.viewContainer.createEmbeddedView(this.templateRef);
  }
}

I use it this way:

<div *hello>Hello Directive</div>

It shows me "Hello Directive" message as expected. Now I want to change the content by wrapping it with some another component:

<my-component>Hello Directive</my-component>

And I want the directive to do it for me. I know that I can use a Component paradigm and create HelloComponent instead of HelloDirective and use ng-template etc with the template defined by template or templateUrl property on the @Component decorator... But is there an approach that could be used with a Directive paradigm to achieve such a result?


回答1:


You can create component dynamically and pass projectable nodes to it. So it could look like

@Directive({ selector: '[hello]' })
export class HelloDirective {
  constructor(
      private templateRef: TemplateRef<any>,
      private viewContainer: ViewContainerRef,
      private resolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
    const templateView = this.templateRef.createEmbeddedView({});
    const compFactory = this.resolver.resolveComponentFactory(MyComponent);
    this.viewContainer.createComponent(
      compFactory, null, this.viewContainer.injector, [templateView.rootNodes])
  }
}

You have to add MyComponent to entryComponents array of your @NgModule

Complete example can be found on Stackblitz

See also

  • Creating a angular2 component with ng-content dynamically


来源:https://stackoverflow.com/questions/47362119/angular-structural-directive-wrap-the-host-element-with-some-another-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!