【问题标题】:How could I use rxjs debounceTime and distinctUntilChanged with angular input events (e.g., click or input)我如何将 rxjs debounceTime 和 distinctUntilChanged 与角度输入事件(例如,单击或输入)一起使用
【发布时间】:2020-06-07 19:52:38
【问题描述】:

如何将 rxjs debounceTimedistinctUntilChanged 与角度输入事件 (input)(click) 一起使用

我不能使用fromEvent,因为我还需要传递参数(示例如下)

<li *ngFor="let item of items>
 <input [(ngModel)]="item.name" (input)="inputChanged(item.id)">
</li>

所以我选择了Subject(示例如下)

<input type="text" placeholder="Type something..." (input)="inputFn($event, 'myParam')"  #myInput>

@ViewChild("myInput", { static: true }) myInput;
private inputEvent = new Subject<any>();

ngOnInit() {
    this.inputEvent
      .pipe(
        // map((obj: any) => obj.evt.target.value),
        debounceTime(1000),
        distinctUntilChanged()
      )
      .subscribe(res => {
        console.log("res", res.evt.target.value);
      });
  }

  inputFn(evt, param) {
    this.inputEvent.next({evt, param});
  }

在上面的例子中,没有使用distinctUntilChanged()。如果我使用 map map((obj: any) =&gt; obj.evt.target.value) 过滤并寻找值变化(不同),我将只获得输入值而不是参数。

我的要求是 - 我想等到用户完成输入文本,并且如果用户重新输入想检查值是否与以前不同并且还想获取参数。

【问题讨论】:

    标签: angular8 rxjs6


    【解决方案1】:

    您必须在distinctUntilChanged 运算符中使用compare function

    import { Component, ViewChild, OnInit } from '@angular/core';
    import { Subject } from 'rxjs';
    import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent implements OnInit {
      @ViewChild("myInput", { static: true }) myInput;
      private inputEvent = new Subject<any>();
    
      ngOnInit() {
        this.inputEvent
          .pipe(
            debounceTime(1000),
            distinctUntilChanged((previous: any, current: any) => previous.value === current.value)
          )
          .subscribe(res => {
            console.log("res", res.evt.target.value);
          });
      }
    
      inputFn(evt, param) {
        this.inputEvent.next({evt, param, value: evt.target.value});
      }
    }
    

    stackblitz

    【讨论】:

    • 它只适用于第一次,如果您在前一个文本之后输入任何新文本,则没有打印控制台日志:(
    • 我已经更新了 stackblitz,现在可以正常使用了。它只在第一次起作用,因为在 distinctUntilChanged 中 event.target.value 的条件失败,“previous”和“current”对 HTML 输入具有相同的引用,因为它是一个对象,因此具有条件中的相同值。所以我在对象中添加了属性值来获得一个原语,现在操作员可以比较一个真实的先前值和一个真实的当前值。
    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2022-01-03
    • 2016-09-16
    • 1970-01-01
    • 2019-07-12
    相关资源
    最近更新 更多