ng bootstrap typeahead 不适用于 angular 反应形式

ng bootstrap typeahead not working with angular reactive form

这是我的组件文件

import {NgbTypeahead} from '@ng-bootstrap/ng-bootstrap';
import { map, switchMap, finalize, debounceTime, distinctUntilChanged, filter } from 'rxjs/operators';
import { Subject, merge } from 'rxjs';

const states = [.....]

// inside class
@ViewChild('instance', {static: true}) instance: NgbTypeahead;
focus$ = new Subject<string>();
click$ = new Subject<string>();

search = (text$: Observable<string>) => {
const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged());
const clicksWithClosedPopup$ = this.click$.pipe(filter(() => !this.instance.isPopupOpen()));
const inputFocus$ = this.focus$;

return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
  map(term => (term === '' ? states
    : states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)).slice(0, 10))
);
}

在我的 html 中,我使用反应式绑定

<input
    id="typeahead-focus"
    type="text"
    class="form-control"
    formControlName="userAssigned" 
    [ngbTypeahead]="search"
    (focus)="focus$.next($event.target.value)"
    (click)="click$.next($event.target.value)"
    #instance="ngbTypeahead"
    />

也像这样在 ngOnInit() 中初始化了我的表单

this.form = this.fb.group({
  userAssigned: ['', Validators.required],
});

当我 运行 此代码并单击输入时,我得到的结果是 pop,但出现此错误。当我清除第一个结果时也无法获得结果。

请帮忙。

问题是声明搜索函数时,"instance is undefined"。这发生在例如如果我们有一些像

<div *ngIf="form" [formGroup]="form">
...
</div>

解决方案是在过滤器中添加this.instance,变成this.instance && !this.instance.isPopupOpen

所以,完成的函数搜索是

    search = (text$: Observable<string>) => {
    const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged());
    const clicksWithClosedPopup$ = this.click$.pipe(filter(() => 
      this.instance && !this.instance.isPopupOpen())); //<---HERE
    const inputFocus$ = this.focus$;

    return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
      map(term => (term === '' ? states
        : states.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)).slice(0, 10))
    );
  }