You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中NG Bootstrap Typeahead绑定Web API新数据格式报错求助

解决NG-Bootstrap Typeahead的TypeError问题

这个报错的原因很明确:你现在的this.si_id数组里存储的是对象,不再是旧格式的字符串了,所以在filter里调用v.toLowerCase()时,对象没有这个方法,直接抛出了TypeError。我们需要针对新的对象数据结构调整代码,分三步解决:

1. 修正搜索过滤逻辑

你需要在过滤时针对对象里的serial_number字段进行匹配,这才是用户要搜索的序列号内容。修改组件里的search函数:

search = (text$: Observable<string>) => text$.pipe(
  debounceTime(200),
  distinctUntilChanged(),
  map(term => term === '' ? [] : this.si_id.filter(item => 
    // 针对对象的serial_number字段做大小写不敏感匹配
    item.serial_number.toLowerCase().indexOf(term.toLowerCase()) > -1
  ).slice(0, 10))
)

2. 调整结果模板的高亮显示

原来的模板里[result]="r"传入的是整个对象,ngb-highlight需要的是要高亮的字符串(也就是serial_number),所以修改模板:

<ng-template #rt let-r="result" let-t="term">
  <ngb-highlight [result]="r.serial_number" [term]="t"></ngb-highlight>
</ng-template>

3. 修复表单初始值的异步问题

注意到你的ngOnInit里直接用this.si_id[0]设置表单初始值,但getSerials是异步HTTP请求,此时si_id还是空数组,初始值会是undefined。你需要在数据加载完成后再设置表单值:

首先调整组件里的getSerials方法:

private getSerials() {
  this.service.getSerials(this.customer_id).subscribe((data) => {
    // 直接赋值数组,不用循环push,更简洁
    this.si_id = data.result;
    // 数据加载完成后,设置表单的初始值
    if (this.si_id.length > 0) {
      this.serviceForm.patchValue({ si_id: this.si_id[0] });
    }
    // 其他逻辑...
  })
}

然后修改ngOnInit里的表单初始化:

ngOnInit() {
  this.getSerials();
  this.serviceForm = new FormGroup({
    customer_id: new FormControl(this.customer_id),
    // 先设置为空,等数据回来再更新初始值
    si_id: new FormControl('', Validators.required),
  });
}

做完这三步,Typeahead就能正常工作了:搜索时会匹配对象里的序列号,结果模板会正确高亮匹配的内容,表单初始值也会在数据加载完成后正确设置。

内容的提问来源于stack exchange,提问作者Sole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:31:20