Angular 从指令中创建/获取TemplateRef

Angular 从指令中创建/获取TemplateRef,angular,angular-material,angular-directive,angular-components,Angular,Angular Material,Angular Directive,Angular Components,我试图创建一个(结构化)指令,插入TemplateRef,但是TemplateRef是在“其他地方”定义的 上下文 我有时想将任意内容插入到现有元素中,但出于DOM的原因,重要的是它不能是组件(尽管类似于组件的属性也可以) 例如: @组件({ 选择器:“tr[我的行组件]” 模板:`` }) 现在,我想做同样的事情,但是在我的表中插入两行。所以我希望做一些类似的事情: 问题是: 我有一个结构化指令,这样我可以插入我想要的代码 我需要一个组件,这样我就可以编写要插入指令的html 问

我试图创建一个(结构化)指令,插入
TemplateRef
,但是
TemplateRef
是在“其他地方”定义的

上下文 我有时想将任意内容插入到现有元素中,但出于DOM的原因,重要的是它不能是组件(尽管类似于组件的属性也可以)

例如:


@组件({
选择器:“tr[我的行组件]”
模板:``
})
现在,我想做同样的事情,但是在我的表中插入两行。所以我希望做一些类似的事情:


问题是:

  • 我有一个结构化指令,这样我可以插入我想要的代码
  • 我需要一个组件,这样我就可以编写要插入指令的html
问题: 如何在结构化指令中获取
TemplateRef
,但该指令的调用方没有传入该指令

@指令({选择器:'[myTwoRowsDirective]})
导出类MyTrowsDirective{
建造师(
viewContainerRef:viewContainerRef){
const templateRef=???;//对在其中定义的模板的引用
createEmbeddedView(templateRef,this.context);
}
}

不知道这是否是一种推荐做法,但这似乎有效(但尚未在您的用例上测试):

@组件({
模板:`
你好
`
})
导出类模板组件{
@ViewChild('helloRef',{static:true})公共helloRef:TemplateRef;
}
@指示({
选择器:“任意组件”
})
导出类CustomizeWhateverDirective在ViewInit之后实现{
私有静态componentRef:componentRef;
建造师(
@Self()private whatever:WhateverComponent,
专用解析程序:ComponentFactoryResolver,
专用录像机:ViewContainerRef
) {}
ngAfterViewInit():void{
const componentRef=this.getComponentRef();
const helloRef=componentRef.instance.helloRef;
this.whatever.helloTemplate=helloRef;
}
私有getComponentRef(){
如果(!CustomizeWhateverDirective.componentRef){
const factory=this.resolver.resolveComponentFactory(TemplatesComponent);
CustomizeWhateverDirective.componentRef=此.\u vcr.createComponent(工厂);
}
返回CustomizeWhateverDirective.componentRef;
}
}
这段代码设置项目中所有组件的helloTemplate属性

因此,诀窍是让一个组件具有templateRef(示例中的TemplatesComponent),并创建该组件(通过viewContainerRef.createComponent)并访问templateRef

@Component({
  template: `
    <ng-template #helloRef>
      <h1>hello</h1>
    </ng-template>
  `
})
export class TemplatesComponent {
  @ViewChild('helloRef', { static: true }) public helloRef: TemplateRef<any>;
}

@Directive({
  selector: 'whatever-component'
})
export class CustomizeWhateverDirective implements AfterViewInit {
  private static componentRef: ComponentRef<TemplatesComponent>;

  constructor(
    @Self() private whatever: WhateverComponent,
    private resolver: ComponentFactoryResolver,
    private _vcr: ViewContainerRef
  ) {}

  ngAfterViewInit(): void {
    const componentRef = this.getComponentRef();

    const helloRef = componentRef.instance.helloRef;
    this.whatever.helloTemplate = helloRef;
  }

  private getComponentRef() {
    if (!CustomizeWhateverDirective.componentRef) {
      const factory = this.resolver.resolveComponentFactory(TemplatesComponent);
      CustomizeWhateverDirective.componentRef = this._vcr.createComponent(factory);
    }

    return CustomizeWhateverDirective.componentRef;
  }
}