Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
zhaosiyang Refactor (#8)
* refactor the code

* update version and upgrade typescript

* change interface to type for CallBackFunction

* better error message
Latest commit a0b00b3 Jun 16, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src Refactor (#8) Jun 16, 2019
.gitignore first version Jan 1, 2019
README.md Refactor (#8) Jun 16, 2019
package-lock.json Refactor (#8) Jun 16, 2019
package.json Refactor (#8) Jun 16, 2019
tsconfig.json modify tsconfig.json Jan 12, 2019

README.md

Property Watch Decorator

This package provides a @OnChange decorator that can be easily used to listen to changes of class properties.

I have a talk at ng-conf 2019 about why this package is useful and how I implement this package.

Install

npm install property-watch-decorator

Example 1

class PersonComponent {
    // Parameter value is inferred as any
    // Parameter change is optional, and inferred as SimpleChange<any>
    @OnChange(function(value, change) {
        console.log(`name is changed from ${change.previousValue} to ${value}`);
    })  
    name: string;
}

Example 2, use generics, better typing

class PersonComponent {
    // Parameter value is inferred as string
    // Parameter change is optional, and inferred as SimpleChange<string>
    @OnChange<string>(function(value, change) {
        console.log(`name is changed from ${change.previousValue} to ${value}`);
    })  
    name: string;
}

Example 3, type this if you want to access other member of the class (just for better IDE integration)

class PersonComponent {
 
    @OnChange<string>(function(this: PersonComponent, value, change) {
        console.log(`name is changed from ${change.previousValue} to ${value}`);
        console.log(`At the moment, age is ${this.age}`)
    })  
    name: string;
    
    age: number;
}

Example 4, using class method reference for onChange (No need to type this as in example 3)

class PersonComponent {
 
    @OnChange<string>('onNameChange')  
    name: string;
    
    age: number;

    onNameChange(value, change) {
      console.log(`name is changed from ${change.previousValue} to ${value}`);
      console.log(`At the moment, age is ${this.age}`);
    }
}

Important notes:

PITFALL 1

Arrow function should be avoided as this would make the function lose context. In this case, this would NOT refer to class instance but undefined For example: it is WRONG to use this way

class MyComponent {
  @OnChange(value => {
      console.log(`property1 is changed to ${value}`);
      console.log(this.property1)  // "this" would refer to undefined, cannot access "property1" of undefined
  })
  property1: any;
}

Correct way

Change arrow function to es5 function:

class MyComponent {
  @OnChange(function(value) {
      console.log(`property1 is changed to ${value}`);
      console.log(this.property1)   // "this" would refer to component instance
  })
  property1: any;
}

PITFALL 2

Callback function CANNOT be referred to class method, this would also cause this to be undefined For example:

class MyComponent {
  @OnChange(this.someFunction) // "this" would refer to undefined, cannot access "someFunction" of undefined
  property1: any;
  
  someFunction(value) {
    console.log(`property1 is changed to ${value}`);
    console.log(this.property1)   
  }
}

Correct way 1

class MyComponent {
  @OnChange('someFunction')
  property1;
  
  someFunction(value) {
      console.log(`property1 is changed to ${value}`);
  }
  
}

Correct way 2

class MyComponent {
  @OnChange(someFunction)
  property1;
}

function someFunction(value) {
    console.log(`property1 is changed to ${value}`);
}
You can’t perform that action at this time.