使用属性装饰器来启动一个类
Posted
技术标签:
【中文标题】使用属性装饰器来启动一个类【英文标题】:Use a property decorator to initiate a class 【发布时间】:2019-10-08 12:43:48 【问题描述】:我正在尝试在 Angular 7 中创建一个属性装饰器,它在 set 变量上启动一个类
export class NewDataClass()
public readonly status = loaded: false
public greet()
return 'hello';
并构建一个装饰器来返回该新类,并带有一些参数
export function NStatus()
return function(target: Object, key: string | symbol): any
return new NewDataClass();
;
@Component(
selector: 'app-new',
templateUrl: './new.component.n.html',
styleUrls: ['./new.component.n.scss']
)
export class NewComponent implements OnInit, OnDestroy
@NStatus() public status: NewDataClass;
当组件初始化时,status
的值应该是new NewDataClass
。帮助
【问题讨论】:
【参考方案1】:您不能直接通过装饰器执行此操作。装饰器在类创建(而不是实例化)时被调用,所以我们所能做的就是改变类本身以满足我们的需要。
一种选择是将字段转换为属性并在 getter 上实例化值:
function NStatus()
return function (target: Object, key: string, desc?: PropertyDescriptor): PropertyDescriptor
return
get: function (this: Record<string, NewDataClass>)
return this["_" + key] || (this["_" + key] = new NewDataClass())
,
set: function (this: Record<string, NewDataClass>, value: NewDataClass)
this["_" + key] = value
class NewComponent
@NStatus() public status: NewDataClass;
console.log(new NewComponent().status);
另一种选择,因为我们谈论的是角度组件,我们可以从装饰器中覆盖 ngOnInit
并在那里执行初始化:
function NStatus()
return function <K extends PropertyKey>(target: ngOnInit?: () => void , key: K): void
const originalNgOnInit = target.ngOnInit;
target.ngOnInit = function (this: Record<K, NewDataClass>)
// Init the field
this[key] = new NewDataClass;
// Call original ngOnInit if any
if(originalNgOnInit) originalNgOnInit.call(this);
class NewComponent
@NStatus() public status: NewDataClass;
ngOnInit ()
const c = new NewComponent()
c.ngOnInit();
console.log(c.status);
很遗憾,无法从属性描述符中截取类构造函数。
【讨论】:
以上是关于使用属性装饰器来启动一个类的主要内容,如果未能解决你的问题,请参考以下文章
react——@修饰器——高阶组件的使用——通过装饰器来调用高阶组件——简单修改样式