【问题标题】:Typescript Decorator gets called twiceTypescript Decorator 被调用两次
【发布时间】:2020-11-02 01:51:20
【问题描述】:

I created an issue report with Typescript 因为我很确定这是一个错误,但我也想在这里检查一下,以防万一有人有更多见解。

这就是正在发生的事情。 When the following code is run:

class Person {
    @IsValueIn(['PETER', 'JAMES'])
    @IsAlpha()
    @IsDefined()
    public name:string;
}

它会记录这个:

Error in /turbo_modules/@fireflysemantics/validator@3.0.10/bundles/fireflysemantics-validator.umd.js (194:21)
The ValidationContainer
already contains context with signature IsValueIn_Person_name.

但是如果我们注释掉@IsValueIn(['PETER', 'JAMES']):

class Person {
    //@IsValueIn(['PETER', 'JAMES'])
    @IsAlpha()
    @IsDefined()
    public name:string;
}

没有例外。

当运行时看到并实例化装饰器时,会调用以下函数(我添加了显示装饰器被调用两次的日志记录语句):

  /**
   * @param target Add a ValidationContext instance.
   * @throws Error if attempting to add a ValidationContext with a signature that duplicates that of an instance already contained.
   * 
   * If an exception thrown it indicates that a duplicate class definition exist
   * in the runtime.  In other words the same class definition is loaded more
   * than once because it exists in multiple files.
   * 
   */
  public static addValidationContext(target: ValidationContext): void {

    const key: string = getPropertyKey(
      target.target.name,
      target.propertyName
    );

    console.log("The property key is: ", key)
    console.log("The target signature is: ", target.getSignature())

这些是执行的日志记录语句:

ValidationContainer.ts:69 The target signature is:  IsDefined_Person_name
ValidationContainer.ts:68 The property key is:  Person_name
ValidationContainer.ts:69 The target signature is:  IsAlpha_Person_name
ValidationContainer.ts:68 The property key is:  Person_name
ValidationContainer.ts:69 The target signature is:  IsValueIn_Person_name
ValidationContainer.ts:68 The property key is:  Person_name
ValidationContainer.ts:69 The target signature is:  IsValueIn_Person_name

可以看出,IsValueIn_Person_name 被创建了两次,因为装饰器实例化发生了两次,这会产生异常。

想法?

【问题讨论】:

标签: javascript typescript typescript-decorator


【解决方案1】:

装饰器根据日志被调用两次的假设是错误的。

在当前来源中:

export function IsValueIn(target: any[], validationOptions?: ValidationOptions) {

  const validationParameters:any[] = [];
  validationParameters.push(target);

  return function(object: any, propertyName: string) {
    const vc: ValidationContext = new ValidationContext(
      object,
      object.constructor,
      IsValueIn.name,
      propertyName,
      validateValue,
      null,
      true,
      errorMessage,
      validationOptions
    );
    ValidationContainer.addValidationContext(vc);
    ValidationContainer.addValidationContext(vc);
  };
}

ValidationContainer.addValidationContext(vc); 被调用两次并产生双日志。

去掉33 or 34 ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-01
    • 2012-05-05
    • 2017-01-19
    • 2014-02-04
    • 2016-12-13
    • 2016-01-30
    • 2015-12-20
    • 2019-04-04
    相关资源
    最近更新 更多