【问题标题】:how do I debounce the @Output of an inner component?如何去抖动内部组件的@Output?
【发布时间】:2016-10-10 13:10:54
【问题描述】:

我有一个组件包装另一个组件<inner-component> 并绑定到InnerComponent.innerChanged() 自定义事件。我想使用@output 属性冒泡,但我也想消除输出抖动。

如何使用RxJS .debounce().debounceTime() 来执行此操作?

类似这样的:

import {Component, Output, EventEmitter} from 'angular2/core';
import 'rxjs/add/operator/debounce';
import 'rxjs/add/operator/debounceTime';

@Component({
  selector: 'debounced-component',
  template: `
    <div>
      <h1>Debounced Outer Component</h1>
      // export class InnerComponent{
      //   @Output() innerChanged: new EventEmitter<string>();
      //   onKeyUp(value){
      //     this.innerChanged.emit(value);
      //   }
      // }
      <input #inner type="text" (innerChange)="onInnerChange(inner.value)">
    </div>
  `
})
export class DebouncedComponent {
  @Output() outerValueChanged: new EventEmitter<string>();

  constructor() {}

  onInnerChange(value) {
    this.outerValuedChanged.emit(value); // I want to debounce() this.
  }
}

【问题讨论】:

  • 好像是this question的副本
  • 我认为不一样,因为我不能使用Observable.fromEvent(),而且我没有FormControl.valueChangesthis.outerValuedChanged.debounce(500).emit(value) 似乎不起作用...

标签: javascript angular rxjs


【解决方案1】:

要对值进行去抖动,您可以使用主题。主体既是可观察者又是观察者。这意味着您可以将其视为可观察对象,也可以将值传递给它。

您可以利用它将新值从内部组件传递给它并以这种方式去抖动它。

export class DebouncedComponent {
  @Output() outerValueChanged: new EventEmitter<string>();
  const debouncer: Subject<string> = new Subject<string>();

  constructor() {
      // you listen to values here which are debounced
      // on every value, you call the outer component
      debouncer
        .debounceTime(100)
        .subscribe((value) => this.outerValuedChanged.emit(value));
  }

  onInnerChange(value) {
    // send every value from the inner to the subject
    debouncer.next(value);
  }
}

这是未经测试的伪代码。您可以在此处 (http://jsbin.com/bexiqeq/15/edit?js,console) 看到该概念的工作示例。它没有角度,但概念保持不变。


更新:对于较新版本的 Angular,您可能需要稍作改动:将 debouncer.debounceTime(100) 更改为 debouncer.pipe(debounceTime(100))

constructor() {
      // you listen to values here which are debounced
     // on every value, you call the outer component
     debouncer
       .pipe(debounceTime(100))
       .subscribe((value) => this.outerValuedChanged.emit(value));
}

【讨论】:

  • 谢谢!我只需要更改为private debouncer: Subject&lt;string&gt; = new Subject&lt;string&gt;(); 即可让 TS 开心。
  • 由于某种原因,这在 Angular2 上不起作用(检查 github 问题)。试试这个方法:stackoverflow.com/questions/32051273/angular2-and-debounce(值被触发而没有任何反跳)
  • 它适用于 angular 2 非常好。谢谢!
  • 你不应该忘记取消订阅 onDestroy
  • 嗨,我怎样才能为取决于给定 ID 的多个传入事件调整此流...所以我得到一堆具有不同对象 ID 的事件,我想为每个目标对象 ID 每 xxx 毫秒?所以我需要为每个对象 id 一个只负责一个对象 id 的去抖动器?
【解决方案2】:

这是一个工作示例类,其中包含所有需要的导入、Angular 4+、TypeScript 和 tslint-friendly :) 认为它可能会帮助一些人寻找我之前正在寻找的东西!

import { Component, Input, Output, EventEmitter, ViewChild, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/debounceTime';

@Component({
  selector: 'app-searchbox',
  template: `
    <input type="text" autocomplete="off" [(ngModel)]="query" [placeholder]="placeholder" (change)="onInputChange($event)">
  `
})
export class SearchboxComponent implements OnDestroy {
  @Input() debounceTime = 500;
  @Output() change = new EventEmitter<string>();

  query = '';
  placeholder = 'Search...';
  results;

  debouncer = new Subject<string>();
  subs = new Array<Subscription>();

  constructor() {
    this.subs.push(this.debouncer.debounceTime(this.debounceTime).subscribe(
      (value: string) => { this.change.emit(value); },
      (error) => { console.log(error); }
    ));
  }

  onInputChange(event: any) {
    this.debouncer.next(event.target.value);
  }

  ngOnDestroy() {
    for (const sub of this.subs) {
      sub.unsubscribe();
    }
  }
}

【讨论】:

  • 我注意到 @Input() debounceTime 如果在 html 中编辑,则不会在此处使用;它总是使用默认值。如何确保它使用自定义值?
  • 你有你提到的 html 的 Jsfiddle 吗?确保您的父 cmp 将数字作为输入发送,例如。 &lt;ChildComponent [debounceTime]="parentDebounceTime"&gt;&lt;/ChildComponent&gt;
猜你喜欢
  • 1970-01-01
  • 2017-06-16
  • 2021-06-30
  • 2021-11-10
  • 2021-11-21
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
相关资源
最近更新 更多