繁体   English   中英

使用属性装饰器来启动类

[英]Use a property decorator to initiate a class

我正在尝试在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的值。 救命

你不能直接从装饰者那里做到这一点。 在类创建(而不是实例化)上调用装饰器,所以我们所能做的就是更改类本身以满足我们的需要。

一种选择是将字段转换为属性并在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);

遗憾的是,不可能从属性描述符中截取类构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM