I have a component with a few inputs that I'd like to be notified when it changes. I currently have it working by implementing ngOnChanges
and figuring out which input was changed. However, I would prefer set my input declaration to @Input('select-values') selectValues:Observable<any>
. This would allow me to subscribe to any new changes that occur in a much cleaner fashion.
ngOnInit() { this.selectValues.subscribe(() => console.log('yay!')); }
Issue with this is that I'm getting exception TypeError: this.selectValues.subscribe is not a function
.
Just found out that this also works – Component Interaction. Intercept input property changes with a setter.
In Angular we can subscribe to an observable in two ways: Manner 1: We subscribe to an observable in our template using the async pipe. The benefit of this is that Angular deals with your subscription during the lifecycle of a component.
Observables provide support for passing messages between parts of your application. They are used frequently in Angular and are a technique for event handling, asynchronous programming, and handling multiple values.
Subscriptions to observables are quite similar to calling a function. But where observables are different is in their ability to return multiple values called streams (a stream is a sequence of data over time). Observables not only able to return a value synchronously, but also asynchronously.
You can wrap them in a form and listen to changes
this.myForm = fb.group({ 'sku': ['', Validators.required] }); this.sku = this.myForm.controls['sku']; this.sku.valueChanges.subscribe( (value: string) => { console.log('sku changed to: ', value); } ); this.myForm.valueChanges.subscribe( (value: string) => { console.log('form changed to: ', value); } );
http://blog.ng-book.com/the-ultimate-guide-to-forms-in-angular-2/
or
@Component({ ..., template: '<input (change)="onChange($event.target.value)">' }) class MyComponent { this.inputChange =new Subject(); onChange(e) { this.inputChange.next(e); } }
See also this issue open https://github.com/angular/angular/issues/4062
In fact, it's not possible to directly register against observables associated with events for DOM elements. You need to reference a DOM element directly and use then the fromEvent
method of Observable
.
Here is a sample:
@Component({ (...) template: ` <input #input /> ` }) export class SomeComponent { @ViewChild('input') input:ElementRef; ngAfterViewInit() { var eventObservable = Observable.fromEvent( this.input.nativeElement, 'keyup'); } }
This issue could interest you as well:
That said you can leverage form controls to be notified when input value is updated. The valueChanges
attribute of the control could be passed as input of the sub component.
@Component({ (...) template: ` <input [ngFormControl]='ctrl'/> <child-component [select-values]="ctrl.valueChanges"></child-component> ` }) export class SomeComponent { constructor() { this.ctrl = new Control(); this.ctrl.valueChanges.subscribe(...); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With