【问题标题】: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。帮助

【问题讨论】:

    标签: angular typescript decorator


    【解决方案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);
    

    很遗憾,无法从属性描述符中截取类构造函数。

    【讨论】:

      猜你喜欢
      • 2013-02-15
      • 2013-09-19
      • 1970-01-01
      • 2017-11-19
      • 2020-11-11
      • 2020-10-04
      • 2017-10-05
      • 2018-12-04
      • 2021-07-16
      相关资源
      最近更新 更多