Как я могу отменить @Output внутреннего компонента?
У меня есть компонент, который обертывает другой компонент <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.
}
}
Ответы
Ответ 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));
}
Ответ 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();
}
}
}