2016-10-10 18 views
9

Tôi có một thành phần bao bọc một thành phần khác <inner-component> và liên kết với sự kiện tùy chỉnh InnerComponent.innerChanged(). Tôi muốn bong bóng bằng cách sử dụng một tài sản @output, nhưng tôi cũng muốn debounce đầu ra.làm cách nào để tôi loại bỏ @Output của một thành phần bên trong?

Làm cách nào để sử dụng RxJS.debounce() hoặc .debounceTime() để thực hiện việc này?

Something như thế này:

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

Có vẻ như bản sao của [câu hỏi này] (http://stackoverflow.com/a/36849347/2435473) –

+0

Tôi không nghĩ rằng nó giống bởi vì tôi không thể sử dụng 'Observable.fromEvent()' và tôi không có 'FormControl.valueChanges'. 'this.outerValuedChanged.debounce (500) .emit (giá trị)' dường như không hoạt động ... – michael

Trả lời

22

Để debounce giá trị mà bạn có thể sử dụng một đề. Một chủ đề vừa là quan sát vừa là người quan sát. Điều này có nghĩa là bạn có thể coi nó là một giá trị quan sát và truyền cho nó.

Bạn có thể tận dụng điều này để chuyển các giá trị mới từ thành phần bên trong đến nó và loại bỏ nó theo cách này.

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

Đây là mã giả chưa được kiểm tra. Bạn có thể xem ví dụ làm việc của khái niệm tại đây (http://jsbin.com/bexiqeq/15/edit?js,console). Nó không có góc cạnh nhưng khái niệm vẫn giữ nguyên.

+1

cảm ơn bạn! Tôi chỉ phải thay đổi thành 'nhà phát hành riêng: Subject = new Subject (); 'để làm TS hạnh phúc. – michael

+0

Điều này vì một số lý do KHÔNG hoạt động trên Angular2 (kiểm tra vấn đề github). Hãy thử cách này: https://stackoverflow.com/questions/32051273/angular2-and-debounce (giá trị được kích hoạt mà không có bất kỳ debounce) –

+0

Nó đang làm việc cho góc 2 hoàn toàn tốt đẹp. Cảm ơn bạn! – Baso

0

Đây là một ví dụ làm việc Lớp học với tất cả các nhập khẩu cần thiết, Góc 4+, TypeScript và tslint thân thiện :) nghĩ rằng nó có thể giúp một số người tìm kiếm những gì tôi đang tìm kiếm những giây phút trước!

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

Các vấn đề liên quan