Keyup事件多次触发

时间:2017-10-16 07:45:44

标签: html angular typescript rxjs

目前,我正在开发Angular 4应用程序。在我的组件Html中,我有一个文本框。每当用户第一次键入任何我想要进行API调用以获取一些数据时。

问题是如果用户输入' A'然后它工作正常并调用API。但是当用户输入" ABC"它正在进行3次API调用。而不是为每个字母进行API调用,只应进行一次调用。

请建议任何解决方案。

组件的HTML:

<input id="inputbox" (keyup)="keyUp($event)"/>

组件:

data: string[]

keyUp(event: any) {
this.loadDataApiCall();
}

loadDataApiCall() {
// calling api to load data.
 //fill data into 
}

我可以在角度4的RXjs的帮助下解决这个问题

7 个答案:

答案 0 :(得分:2)

 Observable.fromEvent(yourDomElement, 'keyup').auditTime(100).subscribe(()=>{
      doSomething();
    });

答案 1 :(得分:1)

您应该在呼叫中添加timeout,并在每次触发时清除它,以便仅呼叫最后一个呼叫。

data: string[]

keyUp(event: any) {
    window.clearTimeout(window.apiCallTimeout);
    window.apiCallTimeout = window.setTimeout(this.loadDataApiCall, 100);
}

loadDataApiCall() {
// calling api to load data.
 //fill data into 
}

这当然意味着呼叫将在用户停止输入后100ms完成。如果他输入&#34; a&#34;过了一会儿,他输入&#34; bc&#34;,然后拨两个电话。当然,您可以增加延迟以满足您的要求。

答案 2 :(得分:0)

如果您只想要一个API调用,则可以使用blur事件,该事件在控件失去焦点时发出:

<input id="inputbox" (blur)="keyUp($event)"/>

答案 3 :(得分:0)

试试这个:

keyUp(event: any) {
this.loadDataApiCall();
event.stopImmediatePropagation();
}

答案 4 :(得分:0)

实现此目的的正确方法是在保存最新值并检查上一个注册值是否与最新注册值匹配后,注册事件并在一段时间后调用API

所以在你的keyup中

keyUp(event: any) {
  this.latestValue = event.target.value;
  this.registerApiCall(event.target.value);
}

注册功能

 registerApiCall(value){
      setTimeout(this.loadDataApiCall.bind(this), 500, value)
    }

api call

loadDataApiCall(value) {
  if (this.latestValue == value ){
    // calling api to load data.
    //fill data into 
  }
}

请参阅this plnk

中的工作示例

编辑:

  

Observable.fromEvent(yourDomElement,'keyup')。auditTime(100).subscribe(()=&gt; {         做一点事();       });

陈杨华的RxJs实现看起来好多了,这里是working plnkr

答案 5 :(得分:0)

如果您愿意将表单更改为Reactive Forms,这将非常简单

this.form.get("input").valueChanges.debounceTime(1000).subscribe((value) => {});

通过反应表单,您可以访问可更改的值更改和状态更改。我们基本上订阅了这个observable,它随时更改会发出值,我们会添加一秒的延迟,这样如果用户仍在输入并更改值,那么它将不会执行我们订阅中的代码。

答案 6 :(得分:0)

@Component({
  selector: 'my-app',
  template: `
    <div>
      <input type="text" (keyup)='keyUp.next($event)'>
    </div>
  ,
})
export class App {
  name:string;

  public keyUp = new Subject<string>();

  constructor() {
    const subscription = this.keyUp
      .map(event => event.target.value)
      .debounceTime(1000)
      .distinctUntilChanged()
      .flatMap(search => Observable.of(search).delay(500))
      .subscribe(console.log);
  }
}