如何使用ngx-bootstrap/typeahead按顺序搜索预设目录下的匹配文件?
问题原因
现有代码仅调用了searchableDirs的第一个目录生成检索规则,没有遍历后续目录,因此只能匹配到第一个目录下的文件。要实现顺序检索、命中即终止的逻辑,需要基于RxJS的顺序流处理能力改造。
改造后实现代码
import { concat, of } from 'rxjs'; import { mergeMap, takeUntil, filter, isEmpty } from 'rxjs/operators'; public dwgs: Observable<any>; // 注意JS字符串中反斜杠需要转义,否则路径会解析错误 searchableDirs = [ 'm:\\592000\\', 'm:\\582500\\', 'm:\\582300\\' ]; constructor() { this.dwgs = Observable.create((observer: any) => { // 这里保留你原有的输入关键词触发逻辑,this.dwg为用户输入的检索关键词 observer.next(this.dwg); }).pipe( mergeMap((keyword: string) => { // 按目录顺序生成检索请求的Observable数组 const searchTasks = this.searchableDirs.map(dir => { const globPattern = `${dir}${keyword}*.+(dwg|DWG)`; return this.globService.getDwgs2(globPattern).pipe( // 过滤空结果,有匹配结果才会向下传递 filter(res => Array.isArray(res) && res.length > 0) ); }); // 按顺序执行检索任务,拿到第一个非空结果就终止后续请求 return concat(...searchTasks).pipe( // 只取第一个匹配到的结果 takeUntil(concat(...searchTasks).pipe(isEmpty())) ); }) ) }
核心逻辑说明
- 用
concat操作符保证目录按预设顺序发起检索请求,不会并发调用 - 每个检索请求后加
filter过滤空结果,只有当前目录下有匹配文件时才会向下传递结果 takeUntil配合isEmpty实现命中即终止的逻辑:只要拿到第一个非空的检索结果,就会停止后续所有目录的检索请求- 所有目录检索完成都没有匹配结果时,会默认返回空流,适配ngx-typeahead的无结果展示逻辑
注意:如果你的
globService.getDwgs2返回的非空匹配结果不是数组格式,请对应修改filter中的结果非空判断规则。
内容的提问来源于stack exchange,提问作者James Morris
相关产品推荐
相关产品推荐

