各位大佬,早上好,中午好,晚上好
今天咱们来聊聊ng-zorro
的drawer
组件在使用服务创建时的一个小坑——自定义footer
的问题。大家都知道,modal
组件可以通过ModalButtonOptions
来定义footer
的按钮,但drawer
的footer
接口却不支持类似的功能。这就导致了一些场景下,我们没法像使用modal
那样灵活地自定义footer
。
问题背景
先来看看drawer
和modal
的footer
接口定义:
-
Drawer的footer接口定义:
-
Modal的footer接口定义:
从图中可以看到,drawer
的footer
只支持TemplateRef
,而modal
的footer
则支持ModalButtonOptions
。这就导致了一些问题:
- 动态创建弹窗时:如果没有组件来定义
TemplateRef
,就无法自定义footer
。 - 动态创建按钮时:如果
footer
的按钮是动态生成的,也无法直接通过TemplateRef
来实现。
解决方案:黑魔法
既然drawer
的footer
只支持TemplateRef
,那我们就从TemplateRef
入手,搞点“黑魔法”来实现类似modal
的ModalButtonOptions
功能。
第一步:定义一个drawer-footer
组件
首先,我们创建一个专门用来处理footer
的组件,命名为drawer-footer
。
HTML部分:
<ng-template #footerTpl>
<div style="float: right">
<button *ngFor="let item of footerBtn" nz-button nzType="item.type" (click)="item.onClick($event)" style="margin-right: 8px;" >{{ item.label }}</button>
</div>
</ng-template>
TypeScript部分:
import { Component, OnInit, Input, ViewChild, TemplateRef } from '@angular/core';
@Component({
selector: 'drawer-footer',
templateUrl: './drawer-footer.component.html',
styleUrls: ['./drawer-footer.component.less']
})
export class DrawerFooterComponent implements OnInit {
@ViewChild('footerTpl', { static: true }) footerTpl!: TemplateRef<any>;
@Input() footerBtn = [];
constructor() { }
ngOnInit(): void {
}
}
第二步:动态创建组件
接下来,我们通过Angular提供的ComponentFactoryResolver
服务来动态创建这个drawer-footer
组件。
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DrawerFooterComponent);
const componentRef = componentFactory.create(this.injector);
componentRef.instance.footerBtn = footer;
这里的footer
是我们定义的按钮数组,比如:
const footer: Array<any> = [
{
label: '流程图',
type: 'text',
onClick: () => {
this.createModalService.openFlowModel(taskInfo.flowInstance.id, formId);
}
},
{
label: '审批意见',
type: 'text',
onClick: () => {
this.createModalService.approvalOpinions(taskInfo.flowInstance.id);
}
}
]
第三步:使用动态创建的TemplateRef
最后,我们将动态创建的TemplateRef
传递给drawer
的nzFooter
属性。
const drawer = this.drawer.create({
nzTitle: name,
nzContent: FormRenderComponent,
nzWidth: this.isMobileTerminal ? '100%' : '66%',
nzFooter: componentRef.instance.footerTpl
});
这样一来,我们就成功模拟了modal
的ModalButtonOptions
功能,实现了动态创建footer
按钮的需求。
done!!
志哥我想说
通过这种“黑魔法”,我们成功绕过了drawer
组件footer
接口的限制,实现了类似modal
的ModalButtonOptions
功能。虽然这个方法有点绕,但在某些场景下确实能解决问题。
不过,我还是想吐槽一下:为啥ng-zorro
的modal
可以有ModalButtonOptions
,而drawer
却没有呢?找了一圈资料,也没看到相关的讨论。如果有大佬知道原因,欢迎在评论区指点一二!