☰
ng-zorro-antd Select 搜索框实战:远程数据搜索(nzServerSearch)与本地过滤完整指南
2026/9/28 3:01:47 网站建设 项目流程
  • UI组件
  • 前端

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

Angular UI Component Library based on Ant Design

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

在 ng-zorro-antd 的 Select 组件中,「搜索框」Demo 演示了如何将可搜索的下拉选择器与远程数据请求相结合:用户输入关键词后,组件把输入值交给后端接口查询,再把返回结果作为选项渲染到下拉列表中。本文以 search-box 示例 为主线,结合 Select 源码 拆解nzShowSearch、nzServerSearch、nzFilterOption、nzOnSearch四个关键 API 的配合方式与底层实现原理,读完即可在真实项目中落地「输入即搜索」的远程数据选择器,并清晰理解它与本地过滤搜索的区别。

一、示例定位:搜索与远程数据结合

仓库中 search-box.md 的描述极为精炼——zh-CN 为「搜索和远程数据结合」,en-US 为「Search with remote data」。它对应的是一个**服务端搜索(Server Search)**场景:选项数据不在前端静态声明,而是由接口按关键词动态返回,适合数据量大、无法一次性下发给前端的业务(如电商商品、用户检索、城市联想等)。

完整的示例实现位于 search-box.ts,核心模板如下:

<nz-select [nzOptions]="options()" nzShowSearch nzServerSearch nzPlaceHolder="input search text" [nzShowArrow]="false" [nzFilterOption]="filterFn" (nzOnSearch)="search($event)" />

对应的组件逻辑:

@Component({ selector: 'nz-demo-select-search-box', imports: [NzSelectModule], template: `<!-- 上述 nz-select 模板 -->`, styles: `nz-select { width: 200px; }` }) export class NzDemoSelectSearchBoxComponent { private readonly http = inject(HttpClient); readonly options = signal<Array<{ label: string; value: string }>>([]); readonly filterFn = (): boolean => true; search(value: string): void { this.http .jsonp<{ result: Array<[string, string]> }>(`YOUR_SUGGEST_API?q=${value}`, 'callback') .subscribe(data => { const options = data.result.map(([item]) => ({ label: item, value: item })); this.options.set(options); }); } }

说明:原示例通过 Angular 的HttpClient.jsonp()访问外部建议类接口(Angular 的 JSONP 能力按约定需要应用引入HttpClientJsonpModule支持),返回的二元组数组被映射为{ label, value }选项列表。实际项目中可将jsonp替换为常规的HttpClient.get()/post()或你自己的数据服务。

该示例有几个一眼可见的细节,都对应 Select 组件的高频配置:

配置取值作用
nzShowSearchtrue开启搜索,使单选模式下也能输入关键词
nzServerSearchtrue声明为服务端搜索,关闭前端本地过滤
[nzFilterOption]() => true过滤函数恒返回true,即“不过滤任何选项”
[nzShowArrow]false隐藏下拉箭头,弱化“下拉”外观、突出“输入搜索”
(nzOnSearch)search($event)输入变化时触发远程请求
[nzOptions]options()选项列表由远程结果动态驱动

二、关键 API 拆解:四个参数如何配合完成远程搜索

要理解这个 Demo,需要把 Select 组件 API 文档 中与搜索相关的四个 API 串起来。它们在 select.component.ts 中均有对应声明:

  • nzShowSearch:类型boolean,默认false,booleanAttribute转换(select.component.ts)。使单选模式可搜索,没有它,输入框不会出现在单选 Select 中。注意组件宿主的ant-select-show-search样式类在nzShowSearch || nzMode !== 'default'时才会挂上(select.component.ts),即多选模式下默认就带搜索输入框。
  • nzServerSearch:类型boolean,默认false(select.component.ts)。是否使用服务端搜索——为true时组件不再在前端对nz-option/nzOptions做过滤,把“哪些选项匹配”完全交给远程数据。
  • nzFilterOption:类型(input?: string, option?: NzSelectItemInterface) => boolean(select.types.ts)。本地过滤模式下判断某个选项是否命中关键词;示例中恒返回true,等价于“保留所有选项,匹配逻辑由远程决定”。
  • (nzOnSearch):EventEmitter<string>(select.component.ts)。文本框值变化时的回调,携带最新输入值,是远程请求的触发点。

此外还有两个常被一起使用的配套项:

  • nzOptions:Array<{ label; value; disabled?; hide?; groupLabel?; ... }>(select.types.ts),可用它取代子组件nz-option声明选项,非常适合以数据驱动、由远程结果批量替换的场景——这正是搜索框 Demo 采用的方式。
  • nzLoading:类型boolean,默认false,用于在请求进行中展示加载态(配合nzShowArrow时的加载图标/搜索图标切换,见 select-arrow 使用处)。

三、源码级原理:远程搜索如何“接管”选项过滤

远程搜索的核心在于:组件内部把“前端过滤”这条链路让位给“远程数据”。以下三段源码可以完整还原这一机制。

1. 默认本地过滤函数

当开发者不传nzFilterOption时,组件使用内置的默认实现defaultFilterOption:

const defaultFilterOption: NzFilterOptionType = (searchValue: string, item: NzSelectItemInterface): boolean => { if (item && item.nzLabel) { return item.nzLabel.toString().toLowerCase().indexOf(searchValue.toLowerCase()) > -1; } return false; };

(select.component.ts)

可见默认规则是对选项标签做忽略大小写的子串匹配(indexOf),这也是nzFilterOption参数的默认值(select.component.ts)。

2. 选项容器的过滤分支

真正决定“本地过滤是否生效”的是updateListOfContainerItem():

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)

关键分支一目了然:只有**「未开启nzServerSearch」且「有输入值」**时,才会调用nzFilterOption过滤;一旦nzServerSearch为true,所有选项原样保留(return true)。这就是为什么远程搜索 Demo 里即使nzFilterOption恒返回true也不会造成“选项被全部保留而混乱”——因为远端接口返回的本来就只是与关键词匹配的结果。

3. 输入事件到远程回调的链路

输入框的每一次变化会沿以下调用链传递:

onInputValueChange(value: string): void { this.searchValue = value; this.updateListOfContainerItem(); this.nzOnSearch.emit(value); // 触发 (nzOnSearch) this.updateCdkConnectedOverlayPositions(); }

(select.component.ts)

即:输入变化 → 更新内部searchValue→ 重建选项容器(这里走的是“远程模式不过滤”的分支)→向外发射nzOnSearch→ 刷新浮层位置。开发者监听nzOnSearch拿到的就是实时的输入文本,可据此发起远程请求。

4. 输入框本身的实现细节

搜索输入框由独立的 select-search.component.ts 渲染,其中值得关注两点:

  • 输入框设置了autocomplete="off"并绑定ngModel(standalone),(ngModelChange)触发onValueChange向上抛值(select-search.component.ts);
  • 组件显式处理了compositionstart/compositionend(select-search.component.ts),并在providers中配置COMPOSITION_BUFFER_MODE = false——这是为了正确区分中文等输入法的组词过程与最终确认,避免拼音拼写过程中就触发远程搜索,是中文场景下的关键细节。

四、从示例到实战:接入你自己的远程数据源

基于上面原理,落地一个远程搜索选择器的通用模式如下:

@Component({ selector: 'app-user-select', imports: [NzSelectModule], template: ` <nz-select [nzOptions]="userOptions()" nzShowSearch nzServerSearch [nzLoading]="loading()" nzPlaceHolder="请输入用户名搜索" [nzFilterOption]="alwaysTrue" (nzOnSearch)="onSearch($event)" /> ` }) export class AppUserSelect { private readonly http = inject(HttpClient); readonly userOptions = signal<Array<{ label: string; value: string }>>([]); readonly loading = signal(false); readonly alwaysTrue = (): boolean => true; onSearch(keyword: string): void { if (!keyword.trim()) { this.userOptions.set([]); return; } this.loading.set(true); this.http .get<Array<{ id: string; name: string }>>(`/api/users?keyword=${encodeURIComponent(keyword)}`) .subscribe({ next: users => this.userOptions.set(users.map(u => ({ label: u.name, value: u.id }))), complete: () => this.loading.set(false) }); } }

结合 搜索框示例 与组件源码,以下是值得注意的工程细节:

  • 结果结构统一映射:无论接口返回什么结构,最终都要映射为{ label, value }(可扩展disabled、groupLabel等字段)赋值给nzOptions,组件便自动完成选项渲染与选中值绑定;
  • 空关键词处理:从onInputValueChange的实现看,空输入同样会触发nzOnSearch,实战中应在回调内对空串提前短路(如上例),避免无效请求;
  • 加载态与错误处理:请求期间用nzLoading呈现加载状态;远程请求失败时建议回填空选项并给出提示(nzNotFoundContent可自定义空数据展示内容);
  • 请求频率:源码每次输入都会同步触发nzOnSearch,高频输入会造成请求风暴,建议按需在回调外层做防抖/竞态处理(如switchMap或取消旧请求),这属于应用层职责;
  • 中文输入:组件已处理好输入法组词阶段不触发搜索,因此composition相关逻辑无需再在业务侧重复处理。

五、本地搜索 vs 远程搜索:何时用哪一种

仓库中另有一个 search 示例(实现见 search.ts),与搜索框示例形成对照:它只设置nzShowSearch与nzAllowClear,选项在组件内静态声明,完全走本地过滤。

<nz-select [nzOptions]="options" nzShowSearch nzAllowClear nzPlaceHolder="Select a person" />

两者的本质区别就一句话:本地搜索的过滤发生在组件内部(默认子串匹配,可用nzFilterOption自定义),远程搜索的过滤发生在服务端(前端不做过滤,选项由接口返回)。

维度本地搜索(search 示例)远程搜索(搜索框示例)
nzServerSearchfalsetrue
选项来源静态声明或一次性加载每次输入动态请求
过滤位置组件内部(nzFilterOption默认子串匹配)服务端,前端恒保留选项
适用场景选项量小、可全量下发数据量大、需按关键词检索
nzOnSearch非必需必需(远程请求的触发点)

判断依据:若你的选项总量可控、能一次加载,用本地搜索即可,省去网络延迟与接口开发;若数据量大、无法全量下发,或需要复杂的服务端检索逻辑,则用远程搜索。若你还需要下拉滚动到底部自动加载更多远程数据,可进一步参考同目录下的 scroll-load 示例(配合nzScrollToBottom输出事件,源码见 select.component.ts)。

六、小结与延伸阅读

「搜索框」Demo 虽短,却完整展示了 ng-zorro-antd Select 服务端搜索的标准用法:nzShowSearch开启输入、nzServerSearch关闭本地过滤、nzFilterOption让位、nzOnSearch承接远程请求、nzOptions动态接管选项。其底层机制——本地过滤分支与nzOnSearch发射链路——在 select.component.ts 与 select.component.ts 中清晰可查。

如果想继续深入,推荐按以下路径阅读仓库相关文件:

  • 示例入口:components/select/demo/search-box.md、components/select/demo/search-box.ts
  • 本地搜索对照:components/select/demo/search.md、components/select/demo/search.ts
  • Select 完整 API:components/select/doc/index.zh-CN.md
  • 组件核心实现:components/select/select.component.ts
  • 搜索输入框实现:components/select/select-search.component.ts
  • 类型定义:components/select/select.types.ts
  • UI组件
  • 前端

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

Angular UI Component Library based on Ant Design

项目地址:https://gitcode.com/gh_mirrors/ng/ng-zorro-antd
点击查看免费下载
上一篇:从仿真到真机:PX4-Avoidance在Intel NUC上的硬件部署全流程
下一篇:可视化编程引擎如何解决低代码开发平台的三大核心挑战

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询