Angular 结构指令:用其他组件包裹宿主元素 [英] Angular structural directive: wrap the host element with some another component

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

问题描述

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

import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';@Directive({ 选择器: '[你好]' })导出类 HelloDirective {构造函数(私有 templateRef: TemplateRef, private viewContainer: ViewContainerRef) {this.viewContainer.createEmbeddedView(this.templateRef);}}

我是这样使用的:

Hello 指令

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

Hello 指令

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

解决方案

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

@Directive({ 选择器: '[hello]' })导出类 HelloDirective 实现 OnInit、DoCheck {模板视图:EmbeddedViewRef;构造函数(私有模板引用:模板引用<任何>,私有视图容器:ViewContainerRef,私有解析器: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(): 无效 {如果(this.templateView){this.templateView.detectChanges();}}}

您必须将 MyComponent 添加到 @NgModule

entryComponents 数组

完整示例可在 Stackblitz

另见

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?

解决方案

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

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

Complete example can be found on Stackblitz

See also

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

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