我正在尝试在输入加密事件上调用服务。
HTML
<input placeholder="enter name" (keyup)='onKeyUp($event)'>
以下是onKeyUp()
功能
onKeyUp(event) {
let observable = Observable.fromEvent(event.target, 'keyup')
.map(value => event.target.value)
.debounceTime(1000)
.distinctUntilChanged()
.flatMap((search) => {
// call the service
});
observable.subscribe((data) => {
// data
});
}
从浏览器的网络标签中发现,它正在调用每个按键事件的按键功能(正如它应该做的那样),但我想要实现的是去抖时间每次服务电话之间1秒。此外,如果我移动箭头键移动,则会触发事件。
答案 0 :(得分:48)
所以这个链是非常正确的,但问题是你正在创建一个Observable并在每个keyup
事件上订阅它。这就是它多次打印相同值的原因。只有多个订阅,这不是你想要做的。
显然有更多方法可以正确地做到这一点,例如:
@Component({
selector: 'my-app',
template: `
<div>
<input type="text" (keyup)='keyUp.next($event)'>
</div>
`,
})
export class App implements OnDestroy {
public keyUp = new Subject<KeyboardEvent>();
private subscription: Subscription;
constructor() {
this.subscription = this.keyUp.pipe(
map(event => event.target.value),
debounceTime(1000),
distinctUntilChanged(),
mergeMap(search => of(search).pipe(
delay(500),
)),
).subscribe(console.log);
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
查看更新后的演示:http://plnkr.co/edit/mAMlgycTcvrYf7509DOP
2019年1月:更新了RxJS 6
答案 1 :(得分:5)
@marlin提供了一个很好的解决方案,它在angular 2.x中可以正常工作,但是在angular 6中,他们开始使用rxjs 6.0版本,并且语法略有不同,因此这里是更新的解决方案。
import {Component} from '@angular/core';
import {Observable, of, Subject} from 'rxjs';
import {debounceTime, delay, distinctUntilChanged, flatMap, map, tap} from 'rxjs/operators';
@Component({
selector: 'my-app',
template: `
<div>
<input type="text" (keyup)='keyUp.next($event)'>
</div>
`,
})
export class AppComponent {
name: string;
public keyUp = new Subject<string>();
constructor() {
const subscription = this.keyUp.pipe(
map(event => event.target.value),
debounceTime(1000),
distinctUntilChanged(),
flatMap(search => of(search).pipe(delay(500)))
).subscribe(console.log);
}
}
答案 2 :(得分:3)
我建议您查看Angular2教程,该教程显示一个类似于您所要求的简洁示例。
https://angular.io/docs/ts/latest/tutorial/toh-pt6.html#!#observables
答案 3 :(得分:0)
嗯,这是一个基本的辩护者。
ngOnInit ( ) {
let inputBox = this.myInput.nativeElement;
let displayDiv = this.myDisplay.nativeElement;
let source = Rx.Observable.fromEvent ( inputBox, 'keyup' )
.map ( ( x ) => { return x.currentTarget.value; } )
.debounce ( ( x ) => { return Rx.Observable.timer ( 1000 ); } );
source.subscribe (
( x ) => { displayDiv.innerText = x; },
( err ) => { console.error ( 'Error: %s', err ) },
() => {} );
}
}
如果您设置了两个指示的视图子项(输入和显示),您将看到去抖动工作。不确定这是不是你做了什么,但是这个基本形式是(据我所知)去抖动的简单方法,我使用这个起点很多,内部文本的集合只是一个例如,它可以进行服务电话或其他任何你需要它做的事情。