javascript - attribute - title tag html
¿Cómo debo rebotar la salida @ de un componente interno? (2)
Tengo un componente que envuelve otro componente <inner-component>
y se enlaza al evento personalizado InnerComponent.innerChanged()
. Quiero hacer una burbuja usando una propiedad @output
, pero también quiero rebotar la salida.
¿Cómo uso RxJS
.debounce()
o .debounceTime()
para hacer esto?
Algo como esto:
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.
}
}
¡Aquí hay una clase de ejemplo de trabajo con todas las importaciones necesarias, Angular 4+, TypeScript y tslint-friendly :) pensó que podría ayudar a algunas personas a buscar lo que estaba buscando hace unos momentos!
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();
}
}
}
Para rebotar valores puedes usar un Asunto. Un sujeto es tanto un observable como un observador. Esto significa que puede tratarlo como un observable y también pasarle valores.
Podría aprovechar esto para pasarle los nuevos valores desde el componente interno a él y rebotarlo de esta manera.
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);
}
}
Este es un pseudo-código no probado. Puede ver un ejemplo práctico del concepto aquí ( http://jsbin.com/bexiqeq/15/edit?js,console ). Es sin angular pero el concepto sigue siendo el mismo.
Actualización: para las versiones más recientes de Angular es posible que necesite un poco: cambiar debouncer.debounceTime(100)
se cambia a 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));
}