how do I debounce the @Output of an inner component?

后端 未结 2 838
闹比i
闹比i 2020-12-15 03:30

I have a component that wraps another component and binds to the InnerComponent.innerChanged() custom event. I want to bubb

相关标签:
2条回答
  • 2020-12-15 04:11

    To debounce values you could use a Subject. A subject is both an observable and a observer. This means you can treat it as an observable and pass values to it as well.

    You could leverage this to pass the new values from the inner-component to it and debounce it this way.

    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);
      }
    }
    

    This is untested pseudo-code. You can see a working example of the concept here (http://jsbin.com/bexiqeq/15/edit?js,console). It's without angular but the concept remains the same.


    Update: For newer versions of Angular you might need a slight: change debouncer.debounceTime(100) gets changed to 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));
    }
    
    0 讨论(0)
  • 2020-12-15 04:21

    Here is a working example Class with all needed imports, Angular 4+, TypeScript and tslint-friendly :) thought it might help some people looking for what I was looking moments ago!

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

    0 讨论(0)
提交回复
热议问题