- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
在 ng-zorro-antd 的 Upload 组件中,文件列表默认展示的预览、删除、下载操作图标以及文件名称旁的信息都是内置固定的。但在真实业务里,我们往往需要把删除图标换成自定义样式、在文件旁追加“文件大小”“上传时间”等额外信息。本指南以仓库自带演示 custom-action-icon.md 与其配套实现 custom-action-icon.ts 为主体,深入讲解如何通过nzShowUploadList传入模板对象来自定义操作图标与文件额外信息,并结合 upload-list.component.html、interface.ts 与 upload-list.spec.ts 的源码实现,让你理解自定义背后完整的渲染链路与可用的进阶能力。
演示功能概览
官方演示的核心只有一句话:通过nzShowUploadList自定义操作图标和文件的额外信息。展开后,它实现了三件事:
- 为每个文件项额外显示
(文件大小 KB)这样的附加文本; - 将下载、删除、预览三个操作按钮的默认图标,分别替换为
snippets、github、apple图标; - 通过预设的
nzFileList(包含 done / error 状态的文件)演示这些自定义内容在真实列表中的呈现位置。
nzShowUploadList 的类型与字段
nzShowUploadList是 Upload 组件的输入属性,既支持布尔值控制列表整体显隐,也支持传入一个对象做精细化定制。其类型定义位于 interface.ts:
export type NzShowUploadListIcon = boolean | ((file: NzUploadFile) => boolean); export interface NzShowUploadList { showRemoveIcon?: NzShowUploadListIcon; showPreviewIcon?: NzShowUploadListIcon; showDownloadIcon?: NzShowUploadListIcon; extra?: TemplateRef<{ $implicit: NzUploadFile }>; downloadIcon?: TemplateRef<{ $implicit: NzUploadFile }>; removeIcon?: TemplateRef<{ $implicit: NzUploadFile }>; previewIcon?: TemplateRef<{ $implicit: NzUploadFile }>; }各字段含义如下:
| 字段 | 类型 | 作用 |
|---|---|---|
extra | TemplateRef<{ $implicit: NzUploadFile }> | 文件名称旁追加的额外信息模板,上下文隐式变量为当前文件对象 |
downloadIcon | TemplateRef<{ $implicit: NzUploadFile }> | 自定义下载操作图标模板 |
removeIcon | TemplateRef<{ $implicit: NzUploadFile }> | 自定义删除操作图标模板 |
previewIcon | TemplateRef<{ $implicit: NzUploadFile }> | 自定义预览操作图标模板(主要作用于picture-card列表样式) |
showRemoveIcon/showPreviewIcon/showDownloadIcon | boolean \| ((file: NzUploadFile) => boolean) | 控制对应图标的显隐,支持布尔值,也支持按文件动态判断的函数 |
需要特别注意的是,四个图标模板的隐式上下文$implicit都是当前NzUploadFile文件对象,因此模板内部可以直接访问file.name、file.size、file.status、file.url、file.response等字段——这正是示例中extra模板能显示文件大小的前提。
此外,upload.component.ts 中的输入 setter 显示:当传入的是布尔值true时,组件会将其展开为默认对象{ showPreviewIcon: true, showRemoveIcon: true, showDownloadIcon: true };false则直接隐藏整个上传列表。
演示代码逐段解析
1. 组件骨架与信号式写法
演示组件位于 custom-action-icon.ts,它采用了 Angular 最新的 signal 风格 API(signal、computed、viewChild):
@Component({ selector: 'nz-demo-upload-custom-action-icon', imports: [NzUploadModule, NzIconModule, NzButtonModule], template: ` <nz-upload [nzShowUploadList]="showUploadList()" [nzFileList]="fileList()"> <button nz-button>Upload</button> </nz-upload> ... ` }) export class NzDemoUploadCustomActionIconComponent { protected readonly downloadIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('downloadIcon'); protected readonly removeIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('removeIcon'); protected readonly previewIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('previewIcon'); protected readonly extra = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('extra'); ... }三个要点值得关注:
- 模板引用通过
viewChild获取:四个ng-template(#extra、#downloadIcon、#removeIcon、#previewIcon)定义在组件模板中,通过viewChild信号读取对应的TemplateRef,再组装进nzShowUploadList对象。 computed派生配置对象:showUploadList是一个computed,内部依赖四个模板引用信号,任何模板引用变化都会触发配置对象重建。- 模块引入:
NzUploadModule(组件本体)、NzIconModule(图标渲染)、NzButtonModule(操作按钮样式)缺一不可。
2. 模板定义:额外信息与三个自定义图标
<ng-template #extra let-file> <span>({{ file.size }} KB)</span> </ng-template> <ng-template #downloadIcon><nz-icon nzType="snippets" /></ng-template> <ng-template #removeIcon><nz-icon nzType="github" /></ng-template> <ng-template #previewIcon><nz-icon nzType="apple" /></ng-template>extra模板通过let-file接收隐式上下文$implicit(即当前文件对象),渲染出(100 KB)、(200 KB)这样的附加文本;其余三个模板则直接返回自定义的nz-icon。示例故意选用了github、apple等非常规图标,目的就是让你直观看到“图标完全可替换”。
computed将四者打包:
protected readonly showUploadList = computed(() => ({ extra: this.extra(), downloadIcon: this.downloadIcon(), removeIcon: this.removeIcon(), previewIcon: this.previewIcon(), showRemoveIcon: true, showPreviewIcon: true, showDownloadIcon: true }));3. 预设文件列表
protected readonly fileList = signal<NzUploadFile[]>([ { uid: '1', name: 'xxx.png', status: 'done', size: 100, response: 'Server Error 500', // custom error message to show url: 'http://www.baidu.com/xxx.png' }, { uid: '2', name: 'yyy.png', size: 200, status: 'done', url: 'http://www.baidu.com/yyy.png' }, { uid: '3', name: 'zzz.png', size: 300, status: 'error', response: 'Server Error 500', // custom error message to show url: 'http://www.baidu.com/zzz.png' } ]);这里有一个容易被忽略的细节:response字段承担了错误消息的展示职责。在 upload-list.component.ts 的genErr方法中:
private genErr(file: NzUploadFile): string { if (file.response && typeof file.response === 'string') { return file.response; } return (file.error && file.error.statusText) || this.locale.uploadError; }当status为error时,列表项会通过 upload-list.component.html 中的nz-tooltip把file.message作为提示文案展示,而file.message正是由genErr生成的。因此,把response写成'Server Error 500'的字符串,悬停错误文件时就能看到这条自定义错误信息。
源码级原理:自定义模板如何被渲染
渲染入口与默认回退
自定义图标模板的消费方是内部组件NzUploadListComponent(nz-upload-list)。在其模板 upload-list.component.html 中:
- 删除按钮(第 69-87 行):若
file.showRemove为真则渲染按钮;按钮内部@if (icons.removeIcon)命中时通过ngTemplateOutlet渲染自定义模板并传入{ $implicit: file }上下文,否则回退到默认的<nz-icon nzType="delete" />。 - 下载按钮(第 89-107 行):逻辑与删除一致,默认回退图标为
nzType="download",同样以$implicit: file作为上下文。 - 预览图标(第 167-172 行):主要出现在
picture-card列表样式的悬停操作区,命中icons.previewIcon时渲染自定义模板,默认回退为<nz-icon nzType="eye" />。 - 额外信息(第 118-124 行):命中
icons.extra时,在ant-upload-list-item-extra容器中渲染模板,插入位置在文件名称之后。
这段模板代码印证了接口定义:每个自定义模板都通过NgTemplateOutlet+NgTemplateOutletContext注入$implicit: file,这正是演示中let-file能取到文件对象、{{ file.size }}能渲染出数值的机制来源。
图标显隐的计算规则
在 upload-list.component.ts 的fixData方法中:
private resolveShowIcon(showIcon: NzShowUploadListIcon | undefined, file: NzUploadFile): boolean { if (!showIcon) { return false; } return typeof showIcon === 'function' ? showIcon(file) : showIcon; } private fixData(): void { this.list.forEach(file => { ... file.showDownload = this.resolveShowIcon(this.icons.showDownloadIcon, file) && file.status === 'done'; file.showRemove = this.resolveShowIcon(this.icons.showRemoveIcon, file); file.showPreview = this.resolveShowIcon(this.icons.showPreviewIcon, file); }); }三个值得记住的实现事实:
showRemoveIcon/showPreviewIcon/showDownloadIcon若传函数,组件会以当前文件为入参调用它,从而支持按文件条件显隐图标;showDownloadIcon额外受file.status === 'done'约束——只有上传成功的文件才显示下载按钮,这就是演示中三个文件都能看到下载按钮(均为 done)的原因;- 未显式配置的 show 字段会按
false处理(resolveShowIcon对空值返回false),因此当你以对象形式传nzShowUploadList时,记得把需要的显隐开关显式置为true,否则对应操作图标不会出现。
测试用例佐证
upload-list.spec.ts 为这些规则提供了可验证的测试:
showRemoveIcon: (file) => file.status === 'done'时,3 个文件中只有 2 个 done 文件出现删除按钮(expect(deleteIcons.length).toBe(2));showDownloadIcon: (file) => file.name === 'xxx.png'时,仅xxx.png一个文件出现下载图标(expect(downloadIcons.length).toBe(1));showPreviewIcon: false时,操作区的<a>预览链接数量为 0。
这些用例从侧面验证了“函数谓词 + done 状态约束 + 显隐开关”三者的组合行为,可作为你自行实现按文件定制操作项时的行为参照。
完整可运行示例
把上述片段整合,即得到一个可直接运行的独立组件(行为与官方演示一致):
import { Component, computed, signal, TemplateRef, viewChild } from '@angular/core'; import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { NzUploadFile, NzUploadModule } from 'ng-zorro-antd/upload'; @Component({ selector: 'app-upload-custom-action-icon', imports: [NzUploadModule, NzIconModule, NzButtonModule], template: ` <nz-upload [nzShowUploadList]="showUploadList()" [nzFileList]="fileList()"> <button nz-button>Upload</button> </nz-upload> <ng-template #extra let-file> <span>({{ file.size }} KB)</span> </ng-template> <ng-template #downloadIcon><nz-icon nzType="snippets" /></ng-template> <ng-template #removeIcon><nz-icon nzType="github" /></ng-template> <ng-template #previewIcon><nz-icon nzType="apple" /></ng-template> ` }) export class UploadCustomActionIconComponent { protected readonly downloadIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('downloadIcon'); protected readonly removeIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('removeIcon'); protected readonly previewIcon = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('previewIcon'); protected readonly extra = viewChild<TemplateRef<{ $implicit: NzUploadFile }>>('extra'); protected readonly fileList = signal<NzUploadFile[]>([ { uid: '1', name: 'xxx.png', status: 'done', size: 100, response: 'Server Error 500', url: 'http://www.baidu.com/xxx.png' }, { uid: '2', name: 'yyy.png', size: 200, status: 'done', url: 'http://www.baidu.com/yyy.png' }, { uid: '3', name: 'zzz.png', size: 300, status: 'error', response: 'Server Error 500', url: 'http://www.baidu.com/zzz.png' } ]); protected readonly showUploadList = computed(() => ({ extra: this.extra(), downloadIcon: this.downloadIcon(), removeIcon: this.removeIcon(), previewIcon: this.previewIcon(), showRemoveIcon: true, showPreviewIcon: true, showDownloadIcon: true })); }运行前提与注意事项:
- 组件所在的模块需引入
NzUploadModule、NzIconModule、NzButtonModule(演示源码 imports 已给出),并在imports数组中声明(当前仓库的演示代码采用独立组件 +imports数组的写法); - 演示使用的是静态
nzFileList,因此不会真正发起上传请求;若改为动态上传,file.size在uploading阶段可能为空,extra模板需做好空值兜底(如{{ file.size ?? '-' }}); - 由于三个自定义图标使用了
github、apple等图标,若你照搬这段代码,请确保项目已动态引入对应图标(ng-zorro-antd 图标支持按需加载,见 icon 模块)。
进阶:按文件动态显隐操作图标
除静态模板外,nzShowUploadList还支持函数形式的显隐开关,实现更细粒度的控制,例如“只允许删除上传成功的文件”“只对指定文件显示下载”:
<nz-upload [nzShowUploadList]="{ showRemoveIcon: (file) => file.status === 'done', showDownloadIcon: (file) => file.name.endsWith('.png'), showPreviewIcon: true }" [nzFileList]="fileList()" > <button nz-button>Upload</button> </nz-upload>对应的组件类型定义见 interface.ts(NzShowUploadListIcon = boolean | ((file: NzUploadFile) => boolean)),实现行为在 upload-list.component.ts 的resolveShowIcon/fixData中,与 upload-list.spec.ts 的测试断言完全一致。
小结
nzShowUploadList是 ng-zorro-antd Upload 组件中控制文件列表形态的“总开关 + 定制面板”:布尔值控制列表显隐,对象形态则通过四个TemplateRef(extra、downloadIcon、removeIcon、previewIcon)与三个显隐开关(showRemoveIcon、showPreviewIcon、showDownloadIcon)实现操作图标、额外信息的完全自定义。所有模板都注入$implicit: NzUploadFile上下文,让你能基于每个文件的真实数据渲染内容;显隐开关还支持函数谓词按文件逐个判定。理解了 interface.ts、upload-list.component.html 与 upload-list.component.ts 的协作关系后,无论是换图标、加文件信息,还是实现复杂的按文件差异化操作,都可以在 Upload 列表层轻松落地。更多 Upload 参数与回调细节可参考 Upload 官方文档 或查看其余演示(如 picture-card.md、preview-file.md)。
- UI组件
- 前端
【免费下载链接】ng-zorro-antd
Angular UI Component Library based on Ant Design
相关推荐
Hermes Agent技术融合:重构云原生AI架构的新范式
Hermes Agent技术融合:重构云原生AI架构的新范式 在AI驱动的数字化转型浪潮中,技术架构师面临着一个核心挑战:如何在保持系统弹性的同时,实现AI能力
UI组件前端ng-zorro-antd Spin 组件自定义指示符(nzIndicator)实战指南
ng zorro antd Spin 组件自定义指示符(nzIndicator)实战指南 加载动效(Spin)是 Angular 应用中缓解用户等待焦虑的关键反
UI组件前端ng-zorro-antd Notification 自定义操作按钮(nzButton)实战指南
ng zorro antd Notification 自定义操作按钮(nzButton)实战指南 本文聚焦 ng zorro antd 通知提醒框(Notifi
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考