После долгих усилий и помощи, которую я получил здесь ( оператор канала работает не так, как ожидалось, 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, differentUntilchanged и т. Д.) Родительскому элементу, затем родительский объект выполняет вызовAPI и отправляет обратно в качестве ввода для ребенка результаты, которые он должен отображать в раскрывающемся списке.Возможно, что все мое направление неверно, и я должен делать это по-другому, пожалуйста, предложите альтернативный подход.Спасибо