请在下面查看我的组件,目的是监听输入的更改,然后将其发送给父组件。我创建了一个仅经常发送一次的管道,并因此最小化了对api的调用,尽管出于某种原因,尽管我可以通过各种console.log
语句看到它进入管道,但每次更改都会发出该值。我想念的是什么?
import {ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output, KeyValueDiffers, DoCheck, KeyValueDiffer} from '@angular/core';
import {BehaviorSubject, Observable, of} from "rxjs";
import {debounceTime, distinctUntilChanged, map, skip, switchMap, takeUntil, tap} from "rxjs/operators";
@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 = '';
// term$ = new BehaviorSubject<string>('');
text$ = new 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();
}
handleTypeahead = (text$: Observable<string>) =>
text$.pipe(
distinctUntilChanged(),
debounceTime(500),
).subscribe((value) => {
this.onTypeahead.emit(of(value))
})
handleSelectItem(item) {
this.onSelect.emit(item);
}
ngDoCheck() {
const change = this.differ.diff(this);
if (change) {
change.forEachChangedItem(item => {
if (item.key === 'detectChange'){
console.log('item changed', item)
this.text$ = of(item.currentValue);
this.handleTypeahead(this.text$);
}
});
}
}
}
更多背景信息:当输入更改时,detectChange
就会被链接到ngDoCheck
,然后调用 handleTypeahead = (text$: Observable<string>) => {
this.test.subscribe(this.text$);
this.test.pipe(
distinctUntilChanged(),
debounceTime(500),
// switchMap(value => text$)
).subscribe((value) => {
tap(console.log('im inside the subscription',value))
this.onTypeahead.emit(value)
})
}
handleSelectItem(item) {
this.onSelect.emit(item);
}
ngDoCheck() {
const change = this.differ.diff(this);
if (change) {
change.forEachChangedItem(item => {
if (item.key === 'detectChange'){
console.log('item changed', item)
this.text$ = of(item.currentValue);
this.handleTypeahead(this.test);
}
});
}
}
}
并执行它。一切都以可观察的方式完成,因此在父级中,我可以订阅传入的事件。
编辑------------------------------------------------- ------------------
根据我对@ggradnig答案的理解,尝试了以下解决方案,可惜它跳过了我的管道,似乎有问题,真的不知道是什么:
AutoMapper.Extensions.Microsoft.DependencyInjection
答案 0 :(得分:0)
您可以执行以下操作-
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 = '';
// term$ = new BehaviorSubject<string>('');
text$ = new BehaviorSubject<string>('');
serachTerm$: 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();
}
// handleTypeahead = (text$: Observable<string>) =>
// text$.pipe(
// distinctUntilChanged(),
// debounceTime(500),
// ).subscribe((value) => {
// this.onTypeahead.emit(of(value))
// })
ngOnInit() {
this.serachTerm$ = this.text$
.pipe(
distinctUntilChanged(),
debounceTime(500),
//filter(), //use filter operator if your logic wants to ignore certain string like empty/null
tap(s => this.onTypeahead.emit(s))
);
}
handleSelectItem(item) {
this.onSelect.emit(item);
}
ngDoCheck() {
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);
}
});
}
}
}
现在,在模板的底部添加以下行-
<ng-container *ngIf="searchTerm$ | async"></ng-container>
具有此行将使您的组件代码自由地用于管理订阅[即不需要订阅/取消订阅];异步管道会处理它。