1.定义一个装饰器,装饰器下面的函数会自动触发
app.component.html
<button nz-button nzType="primary" (click)="method(obj)">decorator</button>
app.component.ts
import { Component, OnInit,} from '@angular/core';
import { Color } from './core/learn-decorator';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
public title:string = '';
public operate:string = 'add';
constructor() {}
ngOnInit() {}
obj = {name: 'lxing', age: 30}
@Color('red')
method(e) {
console.log(e); // {name: 'lxing', age: 30}
console.log('method!!!!!owner');
}
// selectValue(e) {
// console.log(e);
// }
}
装饰器
export function Color(value:string):Function {
//red
console.log(value);
return function(target:Object, key:string | symbol, descriptor:PropertyDescriptor) {
// {constructor: class AppCompent, ngOnInit(), method: fucntion.....}
console.log(target);
// 函数名字 method()
console.log(key);
// {configuable: true, enumerable: false, value: function()......, writable: true}
console.log(descriptor);
const original = descriptor.value;
descriptor.value = function(...args:any) {
// [{name: 'lxing', age: 30}]
console.log(args);
//一定要有这个两行,这样才可以触发外面的事件回调。
const result = original.apply(this, args);
console.log(result)
return result;
}
return descriptor;
}
}
也可以指定函数的名字, 这样触发的函数可以放在任何位子
改变后的代码
import { Component, OnInit,} from '@angular/core';
import { Color } from './core/learn-decorator';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
public title:string = '';
public operate:string = 'add';
constructor() {}
ngOnInit() {}
obj = {name: 'lxing', age: 30}
@Color('red', 'method')
selectValue(e) {
console.log(e);
}
method(e) {
console.log(e); // {name: 'lxing', age: 30}
console.log('method!!!!!owner');
}
}
export function Color(value:string, methodName: string):Function {
//red
console.log(value);
return function(target:Object, key:string | symbol, descriptor:PropertyDescriptor) {
// {constructor: class AppCompent, ngOnInit(), method: fucntion.....}
console.log(target);
// 函数名字 method()
console.log(key);
// {configuable: true, enumerable: false, value: function()......, writable: true}
console.log(descriptor);
const original = descriptor.value;
descriptor.value = function(...args:any) {
// [{name: 'lxing', age: 30}]
console.log(args);
//一定要有这个两行,这样才可以触发外面的事件回调。
const result = original.apply(this, args);
console.log(result)
return result;
}
return descriptor;
}
}
使用场景: 对话框,ngOnChanges的封装,减少重复代码
father.html + ts
<input [(ngModel)]="title"/>
<app-child [title]="title" [operate]="operate"></app-child>
public title:string = '';
public operate:string = 'add';
child.html + ts
<h1>{{title}}--{{operate}}</h1>
import { Component, OnInit, Input, OnChanges } from '@angular/core';
import { TrackChanges } from 'src/app/core/learn-decorator';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.less']
})
export class ChildComponent implements OnChanges {
@Input() title : string = '';
@Input() operate: string = '';
@TrackChanges('title', 'changeDetails')
ngOnChanges() {
console.log('do some operate!!!');
}
changeDetails() {
console.log('value change');
// this.title = 'title'
}
}
装饰器
export function TrackChanges<Type>(key: string, methodName: string): Function {
return function (targetClass, functionName: string, descriptor): Function {
const source = descriptor.value;
descriptor.value = function (changes: SimpleChanges): Function {
console.log(changes);
if (changes && changes[key] && changes[key].currentValue !== undefined) {
console.log(targetClass);
console.log(targetClass[methodName]);
targetClass[methodName].call(this, changes[key].currentValue as Type);
}
return source.call(this, changes);
};
return descriptor;
};
}