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
相关产品推荐
相关产品推荐

