问题
When creating a component in angular 2 that has inputs attributes via @Input, how can I get an observable from the changes made to that attribute @Input (not to be confused with user form input).
export class ExampleComponent implement OnChanges{
@Input() userObject: User;
ngOnChanges(changes: any): void{
// Validate that its the 'userObject' property first
this.doStuff()
}
}
In practice, I would like to merge the Observable changes of the userObject with the Observable changes of other things to have a fluent change reaction pattern.
export class ExampleComponent implement OnChanges{
@Input() userObject: User;
constructor():{
userObject.valueChanges.subscribe(x=>{ this.doStuff() });
}
}
回答1:
I found out the that BehaviorSubject class enables this scenario the best. Instead of creating a separate backend field, you can use the BehaviorSubject's getValue
function to peak at the current value. Then use the backing BehaviorSubject to view as an observable for changes.
export class ExampleComponent{
private _userObject: BehaviorSubject<User> = new BehaviorSubject<User>(null);
@Input()
set userObject(value: User): { this._userObject.next(value); }
get userObject(): User { return this._userObject.getValue(); }
}
回答2:
Try usings a get and a set, valueChanges() below will fire on being set.
private _userObject: User;
@Input()
set userObject(userObject: User) {
this._userObject = userObject;
this.valueChanges();
}
get userObject(): User {
return this._userObject;
}
With an Observable:
private userObjectChange = new Subject<User>();
userObjectChange$ = this.userObjectChange.asObservable();
private _userObject: User;
@Input()
set userObject(userObject: User) {
this.userObjectChange.next(userObject);
this._userObject = userObject;
}
get userObject(): User {
return this._userObject;
}
To subscribe:
this.newQuote.subscribe(user => {...})
回答3:
You can use subject for this:
export class ExampleComponent {
@Input() set userObject(userObject: User) {
this.userObject$.next(userObject);
}
private userObject$ = new Subject<User>();
constructor():{
this.userObject$.subscribe(x=>{ this.doStuff() });
}
}
回答4:
The best way to check the change of an input is actually by using the ngOnChanges
life cycle.
ngOnChanges(changes: { [propertyName: string]: SimpleChange }) {
const changedInputs = Object.keys(changes);
// Only update the userObject if the inputs changed, to avoid unnecessary DOM operations.
if (changedInputs.indexOf('userObject') != -1) {
// do something
}
}
Reference: https://github.com/angular/material2/blob/master/src/lib/icon/icon.ts#L143
来源:https://stackoverflow.com/questions/41274603/observable-of-component-attribute-changes-in-angular2