In Angular2/Typescript, is it possible to "observe" an object's field for changes.
For example, say I have a class Person
with fields firstName
, lastName
, and fullName
. Is it possible to automatically update fullName
whenever either firstName
or lastName
changes?
Something like this:
export class Person {
firstName: string= '';
lastName: string = '';
fullName: string = '';
constructor(firstName: string, lastName: string) {
this.firstName.onChange(() => { this.updateFullName(); });
this.lastName.onChange(() => { this.updateFullName(); });
this.firstName = firstName;
this.lastName = lastName;
}
updateFullName() {
this.fullName = `${this.firstName} ${this.lastName}`;
}
}
First approach
You could leverage TypeScript setters / getters as described below to synchronize fullName with firstName and lastName:
get lastName() {
return this._lastName;
}
set lastName(lastName:string) {
this._lastName = lastName;
this.fullName = this._firstName + ' ' + this._lastName;
}
get firstName() {
return this._firstName;
}
set firstName(firstName:string) {
this._firstName = firstName;
this.fullName = this._firstName + ' ' + this._lastName;
}
This way when setting lastName or firstName, fullName is automatically updated:
var p = new Person();
p.lastName = 'last';
p.firstName = 'first';
console.log(p.fullName); // print 'first last'
Second approach
Angular2 by default doesn't allow to define change of properties within objects. It only detects updates of at references. I mean if the reference (or value for primitive types) of a bound property is updated.
That bien said, Angular2 allows to plugin your own strategy using the ngDoCheck hook method.
In it you can leverage the KeyValueDiffers class (to be injected) to detect updates in specific objects.
See this link for more details:
Here is a sample:
@Component({
selector: 'my-component',
(...)
})
export class MyComponent implements DoCheck {
@Input() person: Person;
differ: any;
constructor(differs: KeyValueDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
var changes = this.differ.diff(this.person);
if (changes) {
changes.forEachChangedItem((elt) => {
if (elt.key === 'firstName' || elt.key === 'lastName' ) {
this.person.fullName = this.person.firstName + ' ' + this.person.lastName;
}
});
}
}
}
When the value of the prop1
property is updated, the doSomethingIfProp1Change
method is called.
See this plunkr: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.
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