经过大量的努力和我在这里获得的帮助(pipe operator not behaving as expected RXJS),我能够让我的子ngbtypeahead组件发出正确的值,并且对api进行了正确的调用,我的问题是我不了解如何让我的ngbtypeahead组件使用data
输入作为列表。
这是我的typeahead-filter.component.ts
:
import {
ChangeDetectionStrategy,
Component, DoCheck,
EventEmitter,
Input,
KeyValueDiffers,
OnChanges,
OnInit,
Output
} from '@angular/core';
import {BehaviorSubject, Observable, of} from "rxjs";
import {debounceTime, distinctUntilChanged, filter, map, switchMap, tap} from "rxjs/operators";
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 DoCheck {
@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[]>;
differ: any;
detectChange: string = '';
text$ = new BehaviorSubject<string>('');
searchTerms$: Observable<string>;
@Output() onTypeahead: EventEmitter<any> = new EventEmitter<any>();
@Output() onSelect: EventEmitter<any> = new EventEmitter<any>();
constructor(private differs: KeyValueDiffers) {
this.differ = this.differs.find({}).create();
this.searchTerms$ = this.text$
.pipe(
distinctUntilChanged(),
debounceTime(500),
filter((value) => value !== ''|| null),
tap(s => this.onTypeahead.emit(s)),
switchMap(term => term === '' ? [] : this.data)
);
}
search = (text$: Observable<string>) => { //this function never happens
console.log('inside function')
return this.text$
}
handleSelectItem(item) {
this.onSelect.emit(item);
}
ngDoCheck() { //if I don't uncomment "search" function then this does not detect change
const change = this.differ.diff(this);
if (change) {
change.forEachChangedItem(item => {
if (item.key === 'detectChange'){
console.log('item changed', item)
this.text$.next(item.currentValue);
}
});
}
}
}
我按照文档中的示例为[ngbTypeahead]="search"
插入了“搜索”功能,由于某种原因,我无法理解,这破坏了ngDoCheck
中的“观察者”,并且不再收听更改,因此不再向父组件发出值。
这意味着我的整个管道都没有响应。
我的模板如下:
<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)]="detectChange"
[ngbTypeahead]="search"
(selectItem)="handleSelectItem($event.item)"
>
{{data | async}}
</div>
<ng-container *ngIf="searchTerms$ | async"></ng-container>
我真正想要的是一个“哑”子组件,该子组件将类型化的值(带有debounce,distinctUntilchanged等)发送给父级,然后父级调用api并将结果作为输入返回给子级它应显示在下拉列表中。我的整体方向有可能是错误的,我应该以不同的方式进行操作,请提出另一种方法。谢谢