使用debounceTime和onFocusOut进行角度2搜索输入

时间:2018-03-14 15:06:04

标签: angular rxjs angular2-forms

我的搜索输入有问题。在Angular 2项目中,我有搜索输入:

 <input [(ngModel)]="data.value" (keyup)="input$.next($event)" (focusout)="onFocusOut($event)" />

和我的typescrirpt:

input$ = new Subject<any>();
ngOnInit() {
  this.input$
    .do(this.keyUpEventHandler.bind(this))
    .debounceTime(3000)
    .distinctUntilChanged()
    .subscribe((value) => {
      console.log('afterDebounce', value);
// do http request in service
        });
  }

  onFocusOut(event) {
    //this.input$.skipLast(1);
   // do http request in service immediately 
  }

我的问题是当我输入...并单击回车时,只是从我的输入组件中丢失焦点,我调用http请求但是在3秒后也再次调用。是否有任何解决方案可以解除输入$ observable的最后一个问题?

我不想取消订阅整个observable,因为我想稍后使用它(如果用户想要搜索数据) 谢谢!

1 个答案:

答案 0 :(得分:2)

您可以创建两个数据流,一个用于'keyUp'事件,另一个用于'blur'事件。比起一点点RxJs魔术做了以下几点:

@ViewChild('searchValueInput') searchValueInput: any;

constructor(private http: HttpClient) {
      }

ngAfterViewInit() {
    this.subscribeToInputChanges();
    }

subscribeToInputChanges(){
  let keyUp$:Observable<any>=Observable.fromEvent     
  (this.searchValueInput.nativeElement, 'keyup')
    .debounceTime(3000)
    .distinctUntilChanged();

let focusOut$:Observable<any>=Observable
.fromEvent(this.searchValueInput.nativeElement, 'blur');

  Observable.defer(()=>Observable.race(
    keyUp$,
    focusOut$
  ))
  .take(1)
  .repeat()
  .subscribe(res=>{
    this.http.get('someURL')
    .subscribe(response=>{
      //Handle response
    })
  })
}

任何你的HTML:

  <input #searchValueInput type="text" class="search" placeholder="Search">

keyUp $ observable与您创建的相同。 focusOut $ observable对keyUp $来说非常纤细,它是从'blur'事件创建的并立即发出数据(没有debounceTime)。

我们使用race operator将它们组合在一起,告诉observable使用第一个发出的observable。

我们还将这个'种族'观察到了另一个defer observable。使用take(1)repeat()的延迟可观察性负责保持订阅活着,而不是总是使用相同的observable(keyUp $或focusOut $)。

我创建了一个小stackblitz,在一个工作示例中显示了以上所有内容。