如何去除内部组件的@Output?

时间:2016-10-10 13:10:55

标签: javascript angular rxjs

我有一个组件包装另一个组件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. } } 执行此操作?

这样的事情:

{{1}}

2 个答案:

答案 0 :(得分:42)

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

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

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

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

答案 1 :(得分:1)

这是一个带有所有需要导入的工作示例类,Angular 4 +,TypeScript和tslint-friendly :)认为它可能会帮助一些人在寻找我刚才看到的东西!

&#13;
&#13;
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();
    }
  }
}
&#13;
&#13;
&#13;