角度6:DebounceTime,仅取最后一个值

时间:2018-08-22 05:38:16

标签: angular rxjs

我有一个输入来搜索数据库中的对象并显示在一个表中,输入是反应性的,当我停止在其中写入1.5秒时进行搜索。为此,我有这段代码

const input = document.getElementById('buscaUsuario');

    fromEvent(input, 'keyup')
      .pipe(
        map((k: KeyboardEvent) => k.target['value']),
        debounceTime(1500),
      ).subscribe(val => {
        console.log(val);
        if (val !== '') {
          console.log('search the user');
          this._usuarioService.buscarUsuarios(val)
            .subscribe( (usuarios: Usuario[]) => {
              this.usuarios = usuarios;
              this.cargando = false;
            });
        }
      });

问题是我放console.log来看看是否只执行一次功能,因为在使用debounceTime之前,应用程序在每次键入键时都会向后端提出新请求。我认为这可以解决我的要求,但是当我放置console.log时,我可以看到该函数执行的数量与输入的字符数量相同。

例如,如果我在输入中输入“ user”,则在控制台中将其输入

  

usuarios.component.ts:84个用户

     

usuarios.component.ts:86搜索用户

     

usuarios.component.ts:84个用户

     

usuarios.component.ts:86搜索用户

     

usuarios.component.ts:84个用户

     

usuarios.component.ts:86搜索用户

在用户停止写入输入1500ms之后,我只能执行一次this._usuarioService.buscarUsuarios一次,该怎么办?

解决方案:

问题在于,我在HTML的输入中放了(keyup)=“ buscarUsuario()”,然后在每个键入中执行了该功能。

解决方案,删除键盘并将我的函数放在ngOnInit中。

这是新代码(感谢Adrian Brand和Krishna Rathore帮助我找到了解决方案)

ngOnInit() {
    this.cargarUsuarios();

    this.cargando = true;

    // Seleccionamos el input en el documento
    const input = document.getElementById('buscaUsuario');

    // En el evento indicado para el elemento seleccionado ejecutamos el pipe y luego el subscribe
    fromEvent(input, 'input')
      .pipe(
        // Tomamos las letras ingresadas
        map((k: KeyboardEvent) => k.target['value']),
        // Seleccionamos un tiempo en milisegundos antes de continuar la ejecución luego de que se presionó la última letra
        debounceTime(1500),
        // Ahora si ejecutamos la busqueda del usuario con el total de letras en el input
        // luego de que se dejara de escribir por 1,5 segundos
      ).subscribe(val => {
        if (val !== '') {
          this._usuarioService.buscarUsuarios(val)
            .subscribe( (usuarios: Usuario[]) => {
              this.usuarios = usuarios;
              this.cargando = false;
            });
        } else {
          this.cargarUsuarios();
          return;
        }
      });

  }

2 个答案:

答案 0 :(得分:3)

您可以尝试使用nativeElement进行绑定keyup事件。

我已在 Stackblitz

上创建了一个演示
  

component.html

<input type="text"  #buscaUsuario>
  

component.ts

import { Component, ViewChild } from '@angular/core';
import { fromEvent } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';

export class AppComponent {
  name = 'Angular';
  @ViewChild('buscaUsuario') buscaUsuario: any;

  ngOnInit() {
    fromEvent(this.buscaUsuario.nativeElement, 'keyup')
      .pipe(
      map((k: KeyboardEvent) => k.target.value),
      debounceTime(1500),
    ).subscribe(val => {
      console.log(val);
      if (val !== '') {
        console.log('search the user');
      }
    });
  }

}

答案 1 :(得分:2)

不确定您在做什么错,但只会在1.5秒后触发我按下的最后一个键。

const { fromEvent } = rxjs;
const { map, debounceTime } = rxjs.operators;

const input = document.getElementById('input');

fromEvent(input, 'keyup')
      .pipe(
        map(k => k.target.value),
        debounceTime(1500),
      ).subscribe(val => {
        console.log(val);
      });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.2/rxjs.umd.min.js"></script>
<input id="input" type="text">