Decorator is a special class declaration, could be added to the method, attribution, and parameter.
Generally speaking, decorator is a method.
1.1 Class Decorator - common decorator - without passing parameters
function logClass(params: string){
console.log(params) ====> params is current class
params.prototype.apiUrl = 'xxxx'; ====> expand the attribution
params.prototype.run = function () { console.log ('running';)};
}
@logClass
class HttpClient{
constructor(){}
getData(){}
}
// Instance
var http: any = new HttpClient();
console.log(http.apiUrl); ====> 'xxxx'
http.run(); ====> 'running';
1.2 Class Decorator Factory - passing parameter
function logClass(params: string){
return function (target: any) {
console.log(target); ====> get www.google.com
console.log(params); ====> get function HttpClient
target.prototype.apiUrl = params;
}
}
@logClass('www.google.com')
class HttpClient{
constructor(){}
getData(){}
}
// Instance
var http: any = new HttpClient();
console.log(http.apiUrl); ====> 'www.google.com'
Reconstruct Constructor
class decorator will be passed as a function, and the constructor is the only parameter. If class decorator has a return, it will use the constructor for the class declaration.
function logClass(params: string){
console.log(params) ====> params is current class
params.prototype.apiUrl = 'xxxx'; ====> expand the attribution
params.prototype.run = function () { console.log ('running';)};
}
@logClass
class HttpClient{
public apiUrl :string | undefined;
constructor(){
this.apiUrl = 'constructor apiUrl';
}
getData(){
console.log(this.apiUrl);
}
}
// Instance
var http: any = new HttpClient();
http.getData(); ====> 'constructor apiUrl';
Reconstructoring
function logClass(target: string){
console.log(target) ====> params is current class
return class extends target{
apiUrl: any = 'modified data';
}
getData(){ ====> notice here must keep identical with HttpClient
this.apiUrl = this.apiUrl + '---';
console.log(this.apiUrl);
}
}
@logClass
class HttpClient{
public apiUrl :string | undefined;
constructor(){
this.apiUrl = 'constructor apiUrl';
}
getData(){
console.log(this.apiUrl);
}
}
// Instance
var http: any = new HttpClient();
http.getData(); ====> 'modified data---';
2.0 Property Decorator
It takes two parameters: constructor for static, prototype for instance
// Class decorator
function logClass(params: string){
console.log(params) ====> params is current class
params.prototype.apiUrl = 'xxxx'; ====> expand the attribution
params.prototype.run = function () { console.log ('running';)};
}
// property decorator
function logProperty(params: any){ ====> params is 'xxxx'
return function (target:any, attr:any){
console.log(target); ====> target is the class HttpClient
console.log(attr); ====> attr is the url, which is the attribution
target.attr = params;
}
}
@logClass('xxxx')
class HttpClient{
@logProperty('www.baidu.com')
public url :string | undefined;
constructor(){
}
getData(){
console.log(this.url);
}
}
// Instance
var http: any = new HttpClient();
http.getData(); ====> 'www.baidu.com';
3.1 Method Decorator - modify current instance property and method
passed with 3 parameters
constructor for static, prototype for instance
method name
method attribution
function get(params:any){
return function(target:any, methodName:any, desc:any){
console.log(target); ====> here is the getData function
console.log(methodName); ====> here is the name --> getData
console.log(desc); ====> here is the detail of getData function
target.apiUrl = 'xxx';
target.run = function(){
console.log('run');
}
}
}
class HttpClient{
public apiUrl :string | undefined;
constructor(){
}
@get('www.zhihu.com')
getData(){
console.log(this.apiUrl);
}
}
// Instance
var http: any = new HttpClient();
http.apiUrl; ====> 'xxx';
http.run(); ====> 'run';
3.2 Method Decorator - modify method
function get(params:any){
return function(target:any, methodName:any, desc:any){
console.log(target); ====> here is the getData function
console.log(methodName); ====> here is the name --> getData
console.log(desc.value);
// to change the method, to add type string to all parameters
//1. Save current method
var oMethod = desc.value;
desc.value = function (...args: any[ ]){
args = args.map( (value) => {
return String(args);
})
console.log(args);
/** oMethod.apply(this,args); ====> this is current function(...args:any[])
====> args is the args inside the function
====> this means oMethod is called inside this function
**/
}
}
}
class HttpClient{
public apiUrl :string | undefined;
constructor(){
}
@get('www.zhihu.com')
getData(...args:any[]){
/**console.log(args)**/ ====> ['123','xxx']
console.log('this is getData method');
}
}
// Instance
var http: any = new HttpClient();
http.getData(123,'xxx') =====> first print getData function
=====> then print ['123', 'xxx']
// it means the getData function has already been replaced,
// but if we want to just modify the getData function, then as following
// new changes will be marked with /** **/
/**
http.getData(123,'xxx') =====> first print ['123', 'xxx']
=====> then print 'this is getData method'
**/
Decorator is a special class declaration, could be added to the
method
,attribution
, andparameter
.Generally speaking,
decorator
is amethod
.1.1 Class Decorator - common decorator - without passing parameters
1.2 Class Decorator Factory - passing parameter
Reconstruct Constructor
class decorator will be passed as a function, and the constructor is the only parameter. If class decorator has a return, it will use the constructor for the class declaration.
Reconstructoring
2.0 Property Decorator
It takes two parameters:
constructor
for static,prototype
for instance3.1 Method Decorator - modify current instance property and method
passed with
3
parametersconstructor
for static,prototype
for instance3.2 Method Decorator - modify method
3.3 Method Parameter Decorator
passed with
3
parametersconstructor
for static,prototype
for instanceOrders of all Decorators
Attribute -> Method -> Method Params -> Class
Multiple with Same, first from the latter ones