ng-bootstrap Typeahead聚焦展开功能报错:无法读取click$、focus$
解决NgbTypeahead触发
click$/focus$ undefined的错误 错误原因
你遇到的Cannot read properties of undefined (reading 'click$')错误,核心是**searchDiagnosis方法的上下文绑定丢失**:当ng-bootstrap框架调用这个方法时,this指向的不是你的组件实例,而是undefined(严格模式下),导致无法访问组件类中定义的click$、focus$等成员变量。
解决方案
方案1:用箭头函数定义搜索方法
箭头函数会自动绑定当前组件的上下文,确保this始终指向组件实例:
import {NgbTypeahead} from '@ng-bootstrap/ng-bootstrap'; import {debounceTime, distinctUntilChanged, filter, map} from 'rxjs/operators'; import { Observable, Subject, merge } from 'rxjs'; @ViewChild('diagnosis', {static: true}) diagnosisInstance: NgbTypeahead; focus$ = new Subject<string>(); click$ = new Subject<string>(); // 改为箭头函数 public searchDiagnosis = (text$: Observable<string>): Observable<string[]> => { const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged()); const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.diagnosisInstance.isPopupOpen())); const inputFocus$ = this.focus$; return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe( map(term => (term === '' ? ['jimmy'] : ['kimmy'])) ); }
方案2:在构造函数中手动绑定上下文
如果偏好普通函数写法,可在组件构造函数中把方法的this绑定到组件实例:
constructor() { // 绑定上下文 this.searchDiagnosis = this.searchDiagnosis.bind(this); } public searchDiagnosis(text$: Observable<string>): Observable<string[]> { // 原代码保持不变 const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged()); const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.diagnosisInstance.isPopupOpen())); const inputFocus$ = this.focus$; return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe( map(term => (term === '' ? ['jimmy'] : ['kimmy'])) ); }
为什么setTimeout无效?
你尝试的setTimeout无法解决问题,因为错误并非click$未初始化,而是调用searchDiagnosis时的this指向错误。延迟打印只是验证了click$本身存在,但方法的上下文问题依然存在。
额外验证点
- 确认
@ViewChild('diagnosis', {static: true})的static属性设置正确:若组件模板中input元素是静态存在(没有*ngIf等动态渲染逻辑),static: true是正确的;若为动态元素,需改为static: false。 - 确保
focus$和click$是组件类的成员变量,而非定义在某个方法内部。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

