2016-10-10 12 views
9

Mam element, który opakowuje inny składnik <inner-component> i wiąże się z niestandardowym zdarzeniem InnerComponent.innerChanged(). Chcę spartanować za pomocą właściwości @output, ale chcę również wycofać dane wyjściowe.Jak zrezygnować z @Output komponentu wewnętrznego?

Jak użyć tej opcji, aby użyć RxJS.debounce() lub .debounceTime()?

coś takiego:

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. 
    } 
} 
+0

Wygląda duplikatu [to pytanie] (http://stackoverflow.com/a/36849347/2435473) –

+0

nie sądzę, że to ten sam, bo nie można używać 'Observable.fromEvent()' i nie mam 'FormControl.valueChanges'. 'this.outerValuedChanged.debounce (500) .emit (wartość)' nie wydaje się działać ... – michael

Odpowiedz

22

Aby nieczułości wartości można użyć przedmiotu. Podmiot jest zarówno obserwowalnym, jak i obserwatorem. Oznacza to, że możesz traktować to jako obserwowalne i przekazywać wartości do niego.

Można to wykorzystać, aby przekazać nowe wartości z wewnętrznego komponentu do niego i usunąć go w ten sposób.

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

To niepoprawny pseudokod. Możesz zobaczyć działający przykład koncepcji tutaj (http://jsbin.com/bexiqeq/15/edit?js,console). Jest bez kątów, ale koncepcja pozostaje taka sama.

+1

dziękuję! Musiałem tylko zmienić na 'private debouncer: Subject = new Subject ();' aby uczynić TS szczęśliwym. – michael

+0

To z jakiegoś powodu NIE działa na Angular2 (sprawdź problemy github). Spróbuj w ten sposób: https://stackoverflow.com/questions/32051273/angular2-and-debounce (wartość jest wywoływana bez żadnego odbicia) –

+0

Działa dla kątowej 2 idealnie dobrze. Dziękuję Ci! – Baso

0

Oto działający przykład Klasa ze wszystkimi potrzebnymi importami, Angular 4+, TypeScript i przyjazna tslint :) Pomyślałem, że może pomóc niektórym osobom szukającym tego, co szukałem chwilę temu!

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

Powiązane problemy