Angular中如何通过exportAs获取组件实例且不渲染子组件?
解决方案
方案一:动态创建组件实例获取模板,避免渲染子组件
如果你不想在父模板中声明<app-child>标签,可以通过Angular组件工厂动态创建子组件实例,不将其视图附加到DOM中,既能拿到模板引用,又不会渲染子组件内容。
修改父组件代码:
import { Component, ComponentFactoryResolver, Injector, OnInit, OnDestroy } from '@angular/core'; import { ChildComponent } from './child.component'; @Component({ selector: 'app-parent', template: ` <div> <ng-container [ngTemplateOutlet]="targetTemplate" [ngTemplateOutletContext]="{ $implicit: parentData }"> </ng-container> </div> `, }) export class ParentComponent implements OnInit, OnDestroy { targetTemplate: TemplateRef<any>; private childComponentRef: any; constructor( private cfr: ComponentFactoryResolver, private injector: Injector ) {} ngOnInit() { // 创建子组件工厂 const childFactory = this.cfr.resolveComponentFactory(ChildComponent); // 创建组件实例,不附加到DOM this.childComponentRef = childFactory.create(this.injector); // 获取子组件中的目标模板 this.targetTemplate = this.childComponentRef.instance.currentHierarchyList; } ngOnDestroy() { // 销毁组件实例,防止内存泄漏 if (this.childComponentRef) { this.childComponentRef.destroy(); } } parentData = '父组件传递的模板数据'; }
同时修正子组件中@ViewChild的选择器(与模板ID匹配):
@Component({ selector: 'app-child', template: ` <ng-container [ngTemplateOutlet]="currentHierarchyList" [ngTemplateOutletContext]="{ $implicit: hierarchyList}"></ng-container> <ng-template #currentHierarchyList let-hierarchyTmplVar> <h1>{{name}}</h1> <!-- 其他模板代码 --> </ng-template> <!-- 子组件自身的其他HTML代码 --> `, styles: [`h1 { font-family: Lato; }`], exportAs: 'compareHierarchyList' }) export class ChildComponent { name = '子模板标题'; hierarchyList = '子组件默认数据'; // 修正选择器,匹配模板中的#currentHierarchyList @ViewChild('currentHierarchyList', { static: true }) currentHierarchyList: TemplateRef<any>; }
方案二:控制子组件自身内容渲染(简单易实现)
如果可以保留<app-child>标签,只需通过输入属性控制子组件自身内容不渲染,仅暴露模板引用:
修改子组件,添加输入属性控制自身内容显示:
@Component({ selector: 'app-child', template: ` <!-- 子组件自身内容,通过isRendered控制是否显示 --> <ng-container *ngIf="isRendered"> <ng-container [ngTemplateOutlet]="currentHierarchyList" [ngTemplateOutletContext]="{ $implicit: hierarchyList}"></ng-container> <!-- 子组件自身的其他HTML代码 --> </ng-container> <ng-template #currentHierarchyList let-hierarchyTmplVar> <h1>{{name}}</h1> <!-- 其他模板代码 --> </ng-template> `, styles: [`h1 { font-family: Lato; }`], exportAs: 'compareHierarchyList' }) export class ChildComponent { @Input() isRendered = true; // 默认渲染自身内容 name = '子模板标题'; hierarchyList = '子组件默认数据'; @ViewChild('currentHierarchyList', { static: true }) currentHierarchyList: TemplateRef<any>; }
父组件中使用时,设置isRendered="false"隐藏子组件自身内容,同时获取模板引用:
@Component({ selector: 'app-parent', template: ` <div> <ng-container [ngTemplateOutlet]="child.currentHierarchyList" [ngTemplateOutletContext]="{ $implicit: parentData }"> </ng-container> <app-child #child="compareHierarchyList" [isRendered]="false"></app-child> </div> `, }) export class ParentComponent { parentData = '父组件传递的模板数据'; }
内容的提问来源于stack exchange,提问作者Mitul Panchal
相关产品推荐
相关产品推荐

