问题
I'm trying to do something after an Observable
/subscribe
completes. I'm changing an Input
property in the subscribe( onNext )
method, but ngOnChanges
never fires.
What should I be doing differently?
import { Component, EventEmitter,
OnInit, AfterViewInit, OnChanges, SimpleChanges,
Input, Output
} from '@angular/core';
@Component({
templateUrl: 'myTemplate.html'
, providers: [ NamesService ]
})
export class MyPage {
@Input() names: any[];
constructor( public namesSvc: NamesService) {}
ngOnInit() {
this.getNames$()
}
getNames$() : void {
this.nameService.get().subscribe(
(result)=>{
this.names = result;
console.log(`getNames$, names=${this.names}`);
// I could doSomething() here, but it doesn't seem like the correct place
// doSomething()
}
, error => this.errorMessage = <any>error
)
}
ngOnChanges(changes: SimpleChanges) : void {
// changes.prop contains the old and the new value...
console.warn(`>>> ngOnChanges triggered`)
if (changes["names"]) {
console.warn(`>>> ngOnChanges, names=${changes["names"]}`)
this.doSomething()
}
}
doSomething(){
console.log("doing something");
}
}
回答1:
That's "as designed"
ngOnChanges()
is only called when change detection updates a binding to an @Input()
. If the input is changed imperatively from somewhere then it isn't called.
Just make names
a getter/setter for code to be executed every time when the property is updated.
回答2:
As stated by Günter it doesn't quite work like that from my understanding... When using Observables you can trigger a change manually with the Observable.next()
feature. The trick here is that you will have to return an Observable
from your service- this can be done like so:
import {Observable, Subject} from "rxjs/Rx"; // remember the '/Rx', it got me...
export class NamesService {
private initialNames: Array<string> = ["Joe", "Jack", "Pete"];
get(){
let names: Subject<Array<string>> = new Subject<Array<string>>();
names.next(this.initialNames);
setTimeout(() => {
this.initialNames.push('someOtherNames');
names.next(this.initialNames);
}, 1000);
return names.asObservable();
}
}
And then subscribe to it much as you have already done, and when the .next()
runs it will trigger a change on the .subscribe()
method.
I would recommend splitting this up from the get method though, you could possible have your own onNameUpdate()
method that return the observable array- or something like that.
来源:https://stackoverflow.com/questions/39913255/ngonchanges-not-firing-when-attribute-changed-by-observable-subscrption