news 2026/9/28 20:09:44

NG-ZORRO Select 默认数据不在选项列表中?用 `nzHide` 优雅实现“默认值但不在下拉选项里“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NG-ZORRO Select 默认数据不在选项列表中?用 `nzHide` 优雅实现“默认值但不在下拉选项里“
  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载

导读

在使用 NG-ZORRO 的nz-select时,经常会遇到一个看似矛盾的需求:表单需要显示一个默认值,但这个默认值并不存在于下拉选项列表中(例如来自后端历史数据、临时占位值,或编辑场景下已下线的选项)。如果强行把它加进选项列表,用户会看到一个多余甚至无法选择的选项;不加,默认值又无法渲染。本篇基于 components/select/demo/default-value.md 及其配套示例,讲解如何借助nz-option的nzHide属性,让默认值既能正确回显、又不会出现在下拉面板中,并深入到源码层面说明其过滤原理。

场景与需求本质

官方演示文档给出了一句精炼的说明(default-value.md):

当需要显示默认值,同时默认值又不在选项列表中时,可以使用nzHide在nz-option中将默认选项隐藏。

即核心诉求是两个状态分离:

  • 已选中态(顶部显示区):默认值必须能正常渲染成标签(tag)或选中文本;
  • 下拉面板(选项列表):默认值对应的选项不应出现在列表中,避免用户重复选择或误以为它是候选值。

nzHide正是为这种"值参与选中、但不参与候选"的选项设计的。

核心 API:nz-option的nzHide

nz-option的完整属性表见 components/select/doc/index.en-US.md,其中与本文相关的属性定义如下:

属性说明类型默认值
[nzLabel]在nz-select和下拉菜单中显示的文本string \| number-
[nzValue]传给nz-select的ngModel的值any-
[nzHide]是否在选项列表中隐藏该选项booleanfalse

在源码 components/select/option.component.ts 中,nzHide通过booleanAttribute转换器声明:

@Input({ transform: booleanAttribute }) nzDisabled = false; @Input({ transform: booleanAttribute }) nzHide = false; @Input({ transform: booleanAttribute }) nzCustomContent = false;

这意味着模板中既可以写nzHide(属性存在即为true),也可以写[nzHide]="someCondition"进行动态绑定。

完整示例:两个典型场景

配套示例源码位于 components/select/demo/default-value.ts,覆盖了多选与单选两种模式,是官方推荐的标准写法:

import { Component, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { NzSelectModule } from 'ng-zorro-antd/select'; @Component({ selector: 'nz-demo-select-default-value', imports: [FormsModule, NzSelectModule], template: ` <nz-select nzMode="multiple" nzPlaceHolder="Inserted are removed" [(ngModel)]="listOfSelectedValue"> @for (option of listOfOption; track option) { <nz-option [nzLabel]="option" [nzValue]="option" /> } @for (option of defaultOption; track option) { <nz-option [nzLabel]="option" [nzValue]="option" nzHide /> } </nz-select> <br /> <br /> <nz-select [(ngModel)]="value"> @for (option of listOfOption; track option) { <nz-option [nzLabel]="option" [nzValue]="option" /> } <nz-option nzLabel="Default Value" nzValue="Default" nzHide /> </nz-select> `, styles: ` nz-select { width: 100%; } ` }) export class NzDemoSelectDefaultValueComponent { readonly listOfOption = ['Option 01', 'Option 02']; readonly listOfSelectedValue = signal(['Default 01', 'Default 02']); readonly value = signal('Default'); get defaultOption(): string[] { return this.listOfSelectedValue(); } }

场景一:多选(nzMode="multiple")

  • 常规候选Option 01、Option 02通过@for渲染为普通nz-option;
  • ngModel初始值为['Default 01', 'Default 02'],这两个值不在候选列表中;
  • 通过第二个@for再渲染一组nz-option,标签和值与默认值完全一致,但加上nzHide属性,使其只负责"占位供选中回显",不进入下拉面板。

此时界面上会呈现两个默认标签,而打开下拉面板时,Default 01、Default 02不会出现。

场景二:单选(默认模式)

单选场景更加直观:在常规选项之后追加一个<nz-option nzLabel="Default Value" nzValue="Default" nzHide />。ngModel初始值为字符串'Default',组件会在所有选项(含隐藏项)中匹配到该值并显示其nzLabel,但用户打开下拉列表时看不到这条"默认值"选项。

注意事项:placeholder 的语义

示例中多选设置了占位符nzPlaceHolder="Inserted are removed"("插入的会被移除"),它传达了一个行为提示:隐藏选项不参与候选匹配,通过输入/搜索插入的、与隐藏项无关的文本不会进入选中集合。占位符只在ngModel为空时显示,一旦隐藏默认值被选中,占位符即消失。

源码原理:隐藏选项如何被过滤

从源码结构看,nzHide的过滤逻辑分为两条路径,最终都汇聚在 components/select/select.component.ts 的updateListOfContainerItem()方法中。

1. 模板驱动(<nz-option>)路径

ngAfterContentInit()中(select.component.ts),组件会收集所有nz-option实例,把nzLabel、nzValue、nzHide等属性逐一映射为内部选项项,存为listOfTagAndTemplateItem。随后在构建下拉面板容器列表时:

let listOfContainerItem = this.listOfTagAndTemplateItem .filter(item => !item.nzHide) .filter(item => { if (!this.nzServerSearch && this.searchValue) { return this.nzFilterOption(this.searchValue, item); } else { return true; } });

(见 select.component.ts)

可见隐藏项在第一步就被剔除,之后才会执行搜索过滤、激活项计算与分组标签插入。这意味着nzHide选项绝不会出现在下拉面板中,也不会被键盘上下键选中。

2. 已选中标签的渲染

关键点在于:隐藏选项虽然被从"容器列表"(下拉面板)过滤掉,但仍保留在listOfTagAndTemplateItem全量集合中。ngOnInit()中通过combineLatest([listOfValue$, listOfTemplateItem$])订阅(select.component.ts),把ngModel的当前值逐一在全量集合中按compareWith匹配,生成listOfTopItem用于顶部显示区渲染。因此隐藏选项既能以标签/文本形式正常回显,又不会进入下拉候选,两个状态互不干扰。

3. 响应式数据驱动([nzOptions])路径

若你更习惯用[nzOptions]传入选项数组而非模板标签,隐藏能力同样存在。NzSelectOptionInterface中定义了hide?: boolean字段(components/select/select.types.ts),在ngOnChanges()转换时被映射为内部nzHide:

const listOfTransformedItem = listOfOptions.map(item => { return { ... nzHide: item.hide || false, ... }; });

(见 select.component.ts)

因此两种数据提供方式都能利用隐藏特性:

listOfOptions = signal([ { label: 'Option 01', value: 'Option 01' }, { label: 'Option 02', value: 'Option 02' }, { label: 'Default 01', value: 'Default 01', hide: true } ]);

测试用例中的佐证

在 components/select/select.spec.ts 的测试组件中,nz-option的[nzHide]="o.nzHide"被作为标准属性参与组件渲染与交互验证;数据驱动模式下同样通过NzSelectItemInterface携带nzHide字段。这从测试层面印证了"隐藏选项作为一等公民参与选中、但不参与候选"的行为契约。

延伸:动态隐藏与清除默认值

nzHide支持动态绑定(booleanAttribute转换),因此可以按状态实时决定是否隐藏。仓库中另一个相关示例 components/select/demo/hide-selected.ts 展示了反向用法——把已选中的选项动态隐藏:

<nz-option [nzLabel]="option" [nzValue]="option" [nzHide]="isSelected(option)" />

其原理与默认值场景完全一致:已选中的选项从下拉面板中消失,避免用户重复选择;取消选中后又恢复显示。这也是nzHide最具实用价值的设计——它把"选中状态"与"候选可见性"解耦,开发者可以自由组合出默认值回显、禁止重复选择、根据条件屏蔽某些选项等交互。

此外需要留意的是:隐藏选项虽然不可在下拉面板中点击选择,但允许通过ngModel初始值注入选中态;一旦用户在多选模式下点击标签的删除按钮删除该默认值,onItemDelete()会将其从listOfValue中移除(select.component.ts),之后由于它不在候选列表中,用户便无法再手动选回——除非重新设置默认值或调整nzHide条件,这一点在业务设计中应提前考虑。

小结

nzHide是 NG-ZORRO Select 在处理"默认值不在选项列表"这一常见表单场景时的官方解法,只需在nz-option上加一个布尔属性即可实现:

  1. 回显不失效:隐藏选项仍参与ngModel值匹配,正常渲染标签与选中文本;
  2. 候选不污染:隐藏选项在updateListOfContainerItem()中被先行过滤,不出现在下拉面板与键盘导航中;
  3. 两种写法通用:模板nz-option nzHide与数据驱动nzOptions中的hide: true均可使用;
  4. 动态可控:booleanAttribute转换使其支持按业务条件实时开合隐藏。

在实际项目中,该方案尤其适用于编辑页回显历史数据、展示已失效/已下线的历史选项、以及"禁止重复选择"类交互,是 Select 组件高价值、低成本的一个隐藏能力。

  • UI组件
  • 前端

【免费下载链接】ng-zorro-antd

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载

相关推荐

上一篇:FacetimeHD 项目常见问题解决方案
下一篇:CANN/asc-devkit贝塞尔函数j0f

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:06:30

询盘留在WordPress后台还是同步CRM?规模是分水岭

询盘记录存在WordPress后台还是同步到CRM&#xff0c;这个问题我被问过不下二十次&#xff0c;答案从来不是非此即彼。先说结论&#xff1a;月询盘量在五十条以内、跟进人少于三个的团队&#xff0c;后台就够用&#xff1b;一旦团队和询盘量往上走&#xff0c;CRM该上就得上。我…

作者头像 李华
网站建设 2026/9/28 20:06:15

论文写作AI工具打分:2026年这6款差距不小

论文写作这事&#xff0c;卡在查重和AI检测上的不在少数。2026年了&#xff0c;市面上的AI写作工具多到挑花眼&#xff0c;但真正能扛住知网、维普那套检测逻辑的&#xff0c;其实没几个。这次我花了三周时间&#xff0c;用经管、计算机、文学三个方向的毕业论文当样本&#xf…

作者头像 李华
网站建设 2026/9/28 20:05:31

使用BP爆破tomcat9用户名+密码 部署jsp后门项目

tomcat官方下载地址如下,此处使用的是tomcat9.0.31 tomcat下载地址 下载后解压即可,然后为了测试使用方便,进行了如下配置 在目录conf下找到文件logging.properties ‌1.打开配置文件‌:用文本编辑器打开 Tomcat 安装目录下的 conf/logging.properties。 ‌2.修改编码‌:找…

作者头像 李华
网站建设 2026/9/28 20:04:33

24年408计组大题深度拆解:Cache映射与指令流水线考点全解析

1. 24年408计组大题到底考了什么先给结论&#xff1a;24年408计算机组成原理的两道大题&#xff08;43题和44题&#xff09;&#xff0c;一道主攻存储器层次与Cache映射&#xff0c;另一道落在指令流水线与数据通路上。这个组合其实不算意外&#xff0c;翻翻过去五年的真题分布…

作者头像 李华
网站建设 2026/9/28 20:04:03

IEPE传感器信号调理:CR隔直电路5个关键参数与避坑指南

IEPE传感器的供电和信号调理&#xff0c;说难不算难&#xff0c;但翻车的概率比很多人想象得高。我调试过一套振动监测采集板&#xff0c;问题就出在CR隔直电路上——一个看似不起眼的电容&#xff0c;直接把低频信号吃掉了一半&#xff0c;当时波形在示波器上怎么看怎么不对。…

作者头像 李华