角度结构指令:将宿主元素与其他组件包装在一起 [英] Angular structural directive: wrap the host element with some another component

查看:75
本文介绍了角度结构指令:将宿主元素与其他组件包装在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有最简单的Angular结构指令:

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);
  }
}

我以这种方式使用它:

<div *hello>Hello Directive</div>

它向我显示了"Hello Directive"消息.现在,我想通过用其他组件包装内容来更改内容:

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>

我希望指令为我做.我知道我可以使用Component范式创建HelloComponent而不是HelloDirective并在@Component装饰器上的templatetemplateUrl属性定义的模板上使用ng-template等...但是在那里可以与指令范式一起使用的方法来实现这样的结果?

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?

推荐答案

您可以动态创建组件并将可投影的节点传递给它.所以看起来像

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

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

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

  ngDoCheck(): void {
    if (this.templateView) {
        this.templateView.detectChanges();
    }
  }
}

您必须将MyComponent添加到@NgModule

完整示例可在 Stackblitz

Complete example can be found on Stackblitz

另请参见

这篇关于角度结构指令:将宿主元素与其他组件包装在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆