我认为您的代码片段中有一些错误
const keydownStream = fromEvent(this.elementRef.nativeElement, 'keyup');
应该
const keyupStream = fromEvent(this.elementRef.nativeElement, 'keyUp');
你真的不需要另一个fromEvent
自从你的keyupStream
已经具有来自的值input
您的 Enter 函数调用和搜索“typeahead”函数调用必须包装在可观察对象中才能取消它们。
鉴于他们是你可以做类似的事情
const search$ = fromEvent(this.search.nativeElement, 'keyup').pipe(share());
const searchKeyEnter$ = search$.pipe(filter((e: KeyboardEvent) => e.keyCode === 13 || e.which === 13))
const searchText$ = search$.pipe(filter((e: KeyboardEvent) => e.keyCode !== 13 && e.which !== 13), debounceTime(500))
const mergeKeyDown = merge(searchText$.pipe(mapTo('search')), searchKeyEnter$.pipe(mapTo('enter')))
.pipe(
withLatestFrom(search$),
filter(([origin, data]) => data.target.value.length > 2),
distinctUntilChanged(),
switchMap(([origin, data]) => {
if (origin === 'search') {
console.log('search started')
return of('').pipe(delay(3000), tap(() => console.log('search call has finished')))
} else {
return of('').pipe(tap(() => console.log(' i got called from enter')));
}
})
).subscribe(() => { })
这里发生的事情是我们共享用户输入内容的事件
fromEvent(this.search.nativeElement, 'keyup').pipe(share());
这样我们就可以分发它来创建和组合特定类型的新可观察量
仅使用 Enter 键的示例:
search$.pipe(filter((e: KeyboardEvent) => e.keyCode === 13 || e.which === 13))
We use mapTo http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mapTo这样我们就可以区分哪个事件被触发了。
当任何这些事件被触发时,我们希望再次重用刚刚从输入更新的值与最新来自 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-withLatestFrom.
现在为了取消任何正在进行的异步任务切换映射 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-switchMap可以使用运算符。
使用 Observables 时的一件大事是创建它们,以便您可以reuse and 创作它们.
我创建了一个 stackblitz,你可以 fork 并亲自尝试一下,注意控制台。
https://stackblitz.com/edit/merging-events?file=src/app/app.component.ts https://stackblitz.com/edit/merging-events?file=src/app/app.component.ts
希望这可以帮助!