Angular Bootstrap Typeahead失焦时无法选中输入值问题
解决ng-bootstrap Typeahead失焦时Model未转为对象的问题
我明白你遇到的困扰了——手动输入完整州名或粘贴内容后点击外部失焦,model会变成字符串而非对应的IStateData对象,只有从下拉列表选择或按Tab键才能正确设置对象类型的model。下面是一个无需切换到ngx-bootstrap就能实现类似“失焦选中”功能的解决方案:
核心思路
在输入框失焦时,手动根据当前输入文本在数据源中查找匹配的对象,找到后将该对象赋值给model;未找到则根据需求选择保持原状态或清空model。
修改后的代码实现
HTML模板部分
给输入框添加blur事件绑定,保留原有属性:
<ng-template #rt let-r="result" let-t="term"> <img [src]="'https://upload.wikimedia.org/wikipedia/commons/thumb/' + r['flag']" width="16"> {{ r.name}} </ng-template> <label for="typeahead-template">Search for a state:</label> <input id="typeahead-template" type="text" class="form-control" [(ngModel)]="model" [ngbTypeahead]="search" [resultTemplate]="rt" [inputFormatter]="formatter" (blur)="handleInputBlur($event)" /> <hr> <pre>Model: {{ model | json }}</pre>
TypeScript组件部分
添加handleInputBlur方法处理失焦时的匹配逻辑:
import {Component} from '@angular/core'; import {Observable} from 'rxjs'; import {debounceTime, map} from 'rxjs/operators'; interface IStateData { name: string; flag: string; } const statesWithFlags: IStateData[] = [ {'name': 'Alabama', 'flag': '5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'}, {'name': 'Alaska', 'flag': 'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'}, {'name': 'Arizona', 'flag': '9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'} ]; @Component({ selector: 'ngbd-typeahead-template', templateUrl: 'src/typeahead-template.html', styles: [`.form-control { width: 300px; }`] }) export class NgbdTypeaheadTemplate { public model: IStateData | undefined; search = (text$: Observable<string>) => text$.pipe( debounceTime(200), map(term => term === '' ? [] : statesWithFlags.filter(v => v.name.toLowerCase().indexOf(term.toLowerCase()) > -1).slice(0, 10)) ); formatter = (x: {name: string}) => x.name; handleInputBlur(event: Event) { const inputValue = (event.target as HTMLInputElement).value.trim(); if (!inputValue) { this.model = undefined; return; } // 大小写不敏感匹配数据源中的州对象 const matchedState = statesWithFlags.find(state => state.name.toLowerCase() === inputValue.toLowerCase() ); if (matchedState) { this.model = matchedState; } // 若需要无匹配项时清空model,可添加以下逻辑: // else { // this.model = undefined; // } } }
关键细节说明
- 大小写兼容:通过
toLowerCase()确保输入文本与数据源州名无论大小写都能匹配 - 空值处理:输入框为空时直接清空model,避免空字符串赋值
- 可扩展性:你可以根据需求调整匹配逻辑,比如支持部分匹配(需额外处理多匹配项的情况)
修改后,无论是从下拉列表选择、按Tab键,还是输入完整名称后失焦,model都会被设置为对应的IStateData对象,不会再变成字符串。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

