我正在使用ngbtypeahead作为自动完成搜索选项,用户键入了一些内容,该键入的值被发送到父组件,该父组件随后对服务器进行调用,然后将返回的值(一个Observable)向下传递给这个孩子。
我想做的是仅在我的switchMap
组件从父组件收到typeAhead
作为data
的情况下,才发出@input
(管道的末端)显示为自动完成选项),data
是服务器调用的结果。最初(在键入任何内容之前)data
为空,因此typeAhead
组件的data
值未定义。
我的问题是,我第一次键入 似乎是在pipe
在typeAhead(子)组件收到data
之前完成,结果导致它显示否自动完成选项。我的代码在下面,我主要遇到的问题是我的handleTypeahead
函数出了什么问题,当我输入自动完成时没有发出类型化的值。
import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {Observable, of} from "rxjs";
import {
debounceTime,
delayWhen,
distinctUntilChanged, filter,
last,
map,
mergeMap,
switchMap,
tap,
withLatestFrom,
} from "rxjs/operators";
import {FilterService} from "@carebox/core";
import {ISearchCriteria} from "@carebox/core";
import {NgbTypeaheadSelectItemEvent} from "@ng-bootstrap/ng-bootstrap";
@Component({
selector: 'core-ui-typeahead-filter',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './typeahead-filter.component.html',
})
export class TypeaheadFilterComponent implements OnInit {
@Input() id: string;
@Input() name: string;
@Input() caption: string;
@Input() placeholder: string;
@Input() cssClass: string;
@Input() cssStyle: string;
@Input() function: any;
@Input() data: Observable<string[]>
model: any;
@Output() onTypeahead: EventEmitter<any> = new EventEmitter<any>();
@Output() onSelect: EventEmitter<any> = new EventEmitter<any>();
constructor() {
}
handleTypeahead = (text$: Observable<string>) => {
this.data.subscribe(
(data) => {
if (data) {
return text$.pipe(
distinctUntilChanged(),
debounceTime(200),
filter(term => term !== ''),
tap((term) => console.log("handleTypeahead", term)),
tap((term) => this.onTypeahead.emit(term)),
/*map((term: string) => [])*/
/*map((term: string) => term === '' ? [] : this.data)*/
// withLatestFrom(this.data),
switchMap(() => this.data)
);
}
}
)
}
handleSelectItem(item) {
this.onSelect.emit(item);
}
ngOnInit() {
// this.data.subscribe()
}
}
相关模板:
<div class="form-group">
<label class="label-filters" for="{{id}}">
{{caption}}
</label>
<input id="{{id}}"
name="{{name}}"
type="text"
placeholder="{{placeholder}}"
class="{{cssClass}}"
style="{{cssStyle}}"
autocomplete="off"
[(ngModel)]="model"
[ngbTypeahead]="handleTypeahead"
(selectItem)="handleSelectItem($event.item)"
>
</div>
我尝试过的一种解决方案是简单地添加具有500ms延迟的delay
运算符,但这可行,但并不美观,并且存在其他一些问题。应该有一种方法可以明确地等待@input值进入。
在父组件以及模板中添加相关代码:
/* NctId Filter */
public NctIdTypeahead(term: string) {
this.model.NctIdList = [];
if (!(term && term.length > 0)) {
return;
}
this.searchCriteria.nctIdPrefix = term;
this.searchCriteria.aggregateOn = 'nctid';
this.filterService.GetNctIdFilterData(this.searchCriteria).pipe(
last(),
map((result: any) => {
return result.nctid;
})
).subscribe(id => this.NctIdList = of(id))
}
以及(父项的)模板:
<div class="col-sm-6 col-md-4 col-lg-3">
<core-ui-typeahead-filter
id="NctIdFilter"
caption="NCT ID"
placeholder="Type to select NCT ID"
i18n-placeholder="@@T-trials.trial_protocol_id_filter_placeholder"
[data]="NctIdList"
[cssClass]="'form-control'"
(onTypeahead)="NctIdTypeahead($event)"
(onSelect)="NctIdSelect($event)">
</core-ui-typeahead-filter>
</div>