Angular 13:如何通过指令与<ng-template>实现内容向下投影?
解决方案
1. 包装子组件为模板
修改page.component.html,将<child-component>包裹在<ng-template>中并添加模板引用:
<app-component-w-directive> <ng-template #sharedChild> <child-component></child-component> </ng-template> </app-component-w-directive>
2. 在容器组件中获取模板引用
在component-w-directive.component.ts中,通过@ContentChild获取这个模板:
import { Component, ContentChild, TemplateRef } from '@angular/core'; @Component({ selector: 'app-component-w-directive', templateUrl: './component-w-directive.component.html' }) export class ComponentWDirectiveComponent { @ContentChild('sharedChild') sharedChildTemplate: TemplateRef<any>; someValues = {}; // 你的业务数据 }
3. 向动态生成组件传递模板
修改component-w-directive.component.html,将模板引用传递给指令:
<ng-template myCustomDirective [someInputs]="someValues" [childTemplate]="sharedChildTemplate" > </ng-template>
4. 在动态组件中使用模板
在casted-from-directive.component.ts中添加输入属性接收模板:
import { Component, Input, TemplateRef } from '@angular/core'; @Component({ selector: 'app-casted-from-directive', templateUrl: './casted-from-directive.component.html' }) export class CastedFromDirectiveComponent { @Input() childTemplate: TemplateRef<any>; }
修改其模板,用ngTemplateOutlet渲染传入的模板:
<!-- 原有HTML代码 --> <ng-container [ngTemplateOutlet]="childTemplate"></ng-container> <!-- 原有HTML代码 -->
5. 更新动态创建组件的逻辑
在myCustomDirective的实现中,创建动态组件时将模板赋值给组件输入属性:
import { Directive, Input, ViewContainerRef, ComponentFactoryResolver } from '@angular/core'; import { CastedFromDirectiveComponent } from './casted-from-directive.component'; @Directive({ selector: '[myCustomDirective]' }) export class MyCustomDirective { @Input() set childTemplate(template: TemplateRef<any>) { this._childTemplate = template; this.renderComponent(); } @Input() someInputs: any; private _childTemplate: TemplateRef<any>; constructor( private vcr: ViewContainerRef, private cfr: ComponentFactoryResolver ) {} private renderComponent() { this.vcr.clear(); const factory = this.cfr.resolveComponentFactory(CastedFromDirectiveComponent); const componentRef = this.vcr.createComponent(factory); // 传递输入属性 componentRef.instance.childTemplate = this._childTemplate; componentRef.instance.someInputs = this.someInputs; } }
通过这种方式,就能将page.component.html中的<child-component>共享给所有动态生成的组件。
内容的提问来源于stack exchange,提问作者Pato
相关产品推荐
相关产品推荐

