Angular集成ng-bootstrap Typeahead遇报错及跳转需求求助
解决ng-bootstrap Typeahead的类型错误与跳转需求
首先来说你遇到的TS2339错误——问题出在你的search函数里的嵌套filter逻辑上。看这段代码:
map(([term, list]) => term === '' ? [] : list.filter((v:any) => list.filter(v => v.searchitem.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)))
外层list.filter的回调里,你又重复调用了list.filter,这时候内层的v是单个Search对象(不是数组),所以当你试图对它调用filter方法时,就会抛出“Property 'filter' does not exist on type 'Search'”的错误。而且这个嵌套逻辑完全没必要,我们只需要直接过滤数组即可。
第一步:修复类型错误
把search函数改成下面这样,逻辑更清晰,也能解决类型问题:
search = (text$: Observable<string>) => text$.pipe( debounceTime(200), withLatestFrom(this.searchList), map(([term, list]) => { if (term.trim() === '') return []; const lowerCaseTerm = term.toLowerCase(); // 直接过滤数组,找到包含搜索词的项,截取前10个 return list .filter(item => item.searchitem.toLowerCase().includes(lowerCaseTerm)) .slice(0, 10); }) );
这里我们先把搜索词转成小写,然后遍历list里的每个Search对象,检查searchitem是否包含这个小写词,最后截取前10项返回。
第二步:实现点击搜索跳转对应URL
要完成点击搜索按钮跳转的需求,我们需要做这几件事:
- 明确model类型:把组件里的
model类型从any改成Search | undefined,这样能更好地获取url属性:
public model: Search | undefined;
- 添加表单提交处理方法:在组件类里添加一个处理表单提交的函数,负责跳转:
onSearchSubmit(event: Event) { // 阻止表单默认的刷新行为 event.preventDefault(); // 确保model存在且有url属性,再跳转 if (this.model?.url) { window.location.href = this.model.url; } }
- 绑定表单提交事件:修改HTML里的表单,把
ngSubmit事件绑定到上面的方法:
<form class="form-inline my-2 my-lg-0" (ngSubmit)="onSearchSubmit($event)"> <ng-template #rt let-r="result" let-t="term"> {{ r.searchitem}} </ng-template> <input type="search" class="form-control mr-sm-2" #instance="ngbTypeahead" placeholder="Search" aria-label="Search" [(ngModel)]="model" [ngbTypeahead]="search" [resultTemplate]="rt" [inputFormatter]="formatter" (focus)="focus$.next($event.target.value)" (click)="click$.next($event.target.value)" > <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form>
- 实现inputFormatter(可选但推荐):如果你还没实现这个函数,添加它让输入框显示选中的搜索项文本:
formatter = (result: Search) => result.searchitem;
额外优化:服务的依赖注入
为了让服务的注入更规范,建议在SearchService里使用providedIn: 'root'(Angular 6+的推荐方式),这样就不用手动在模块的providers里声明了:
import { Injectable } from '@angular/core'; import { Search } from '../data/search'; import { SEARCH } from '../data/searchdata'; @Injectable({ providedIn: 'root' }) export class SearchService { constructor() { } getSearch(): Search[]{ return SEARCH; } }
这样修改后,你的Typeahead应该能正常显示搜索建议,点击搜索按钮也会跳转到对应的URL了。
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

