如何通过ng-content向模态框投影的子组件传递数据?
实现方案
给ng-content投影的组件传数据,Angular有三种常用的实现方式,你可以根据自己的业务场景选择:
方案1:@ContentChild 直接操作投影组件实例(改造成本最低)
如果你的自定义模态框仅适配固定的几个投影组件,用这个方案最方便:
- 首先在自定义modal组件的ts文件中,通过
@ContentChild获取投影进来的组件实例,直接给实例的输入属性赋值:
import { Component, Input, ContentChild, OnChanges, SimpleChanges } from '@angular/core'; // 导入投影组件的类 import { CreateNewItemModalComponent } from './create-new-item-modal.component'; @Component({ selector: 'modal', templateUrl: './modal.component.html' }) export class ModalComponent implements OnChanges { // 对外暴露输入属性,接收上层要传给投影组件的数据 @Input() innerData: any; // 获取投影的createNewItem-modal组件实例 @ContentChild(CreateNewItemModalComponent) contentComponent?: CreateNewItemModalComponent; ngOnChanges(changes: SimpleChanges): void { // 当传入的数据变化时,同步更新到投影组件 if (changes['innerData'] && this.contentComponent) { this.contentComponent.yourInputProp = this.innerData; } } }
- 使用的时候直接给自定义modal传数据即可:
<modal title="Create New Item" id="createNewItemModal" [innerData]="outerComponentData" > <createNewItem-modal></createNewItem-modal> </modal>
方案2:改用ng-template投影(通用模态框推荐)
如果你的模态框是通用组件,需要支持任意类型的投影内容,推荐把原来的ng-content替换为ngTemplateOutlet,通过上下文传值:
- 先修改自定义modal的模板:
<nz-modal [nzWidth]="width" [nzTitle]="title" [nzVisible]="id === currentModal" [nzClosable]="closable" [nzFooter]="null" [nzCentered]="true" (nzOnCancel)="hideModal()" > <ng-container *nzModalContent> <!-- 替换ng-content为ngTemplateOutlet,同时传入上下文数据 --> <ng-container *ngTemplateOutlet="contentTpl; context: modalContext"></ng-container> </ng-container> </nz-modal>
- 自定义modal的ts文件新增对应属性:
import { Component, Input, TemplateRef } from '@angular/core'; @Component({ selector: 'modal', templateUrl: './modal.component.html' }) export class ModalComponent { // 接收外部传入的模板 @Input() contentTpl?: TemplateRef<any>; // 定义要传递给投影内容的上下文数据 modalContext = { customData: { /* 这里放你要传递的任意数据 */ } }; }
- 使用的时候把投影内容放在ng-template中,接收上下文后传给对应组件:
<modal title="Create New Item" id="createNewItemModal" [contentTpl]="itemModalTpl" ></modal> <ng-template #itemModalTpl let-data="customData"> <createNewItem-modal [inputProp]="data"></createNewItem-modal> </ng-template>
方案3:服务共享状态(复杂交互场景适用)
如果涉及多层组件嵌套、数据需要双向同步等复杂场景,可以单独建一个模态框服务,用RxJs的Subject/BehaviorSubject存数据,自定义modal中发布数据,投影组件订阅服务拿数据即可,这种方案解耦性最高。
内容的提问来源于stack exchange,提问作者Safa
相关产品推荐
相关产品推荐

