如何将实例变量传递给typescript装饰器参数?

时间:2021-11-28 23:18:19

How to implement a typescript decorator? is a good example about how to use decorator in typescript.

如何实现打字稿装饰器?关于如何在打字稿中使用装饰器是一个很好的例子。

Considering the below case,

考虑到以下情况,

class MyClass {
    @enumerable(false)
    get prop() {
        return true;
    }

    @property({required: true}) //here pass constant is no issue
    public startDateString:string;

    @property({afterDate: this.startDateString}) //how to pass startDateString here?
    public endDateString:string;
}

function enumerable(isEnumerable: boolean) {
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
        descriptor.enumerable = isEnumerable;
        return descriptor;
    };
}

I tried everything but it seems I have no way to pass startDateString into decorator argument. startDateString could be a variable, a function and a reference.

我尝试了一切,但似乎我无法将startDateString传递给decorator参数。 startDateString可以是变量,函数和引用。

2 个解决方案

#1


7  

What you are trying to do is not possible.

你想要做的是不可能的。

Decorators get called when the class is declared and at this time there is no instance to pass into the decorator.

声明类时会调用装饰器,此时没有实例传递给装饰器。

For example, with this code:

例如,使用此代码:

class MyClass {
    startDateString: string;
    @property({ afterDate: this.startDateString })
    endDateString: string;
}
let myClass = new MyClass();
  1. MyClass is declared.
  2. 声明了MyClass。
  3. The decorators are run on MyClass. There is no instance that exists to pass in at this point and this in the decorator argument refers to the global object—not an instance.
  4. 装饰器在MyClass上运行。此时没有传入的实例,而decorator参数中的这个实例引用的是全局对象 - 而不是实例。
  5. new MyClass() is called and the instance is created. Decorators aren't called on this step. That already happened.
  6. 调用新的MyClass()并创建实例。此步骤不会调用装饰器。那已经发生了。

Take a look at the compiled JavaScript for reference:

看看编译的JavaScript以供参考:

var MyClass = (function () {
    // -- 1 --
    function MyClass() {
    }
    // -- 2 --
    __decorate([
        // see here... `this` is equal to the global object
        property({ afterDate: this.startDateString })
    ], MyClass.prototype, "endDateString", void 0);
    return MyClass;
})();
// -- 3 --
var myClass = new MyClass();

Note that using this.startDateString doesn't throw a compile error here because this is typed as any.

请注意,使用this.startDateString不会在此处引发编译错误,因为这是任何类型。

So what is trying to be done here by passing in an instance property doesn't make sense and isn't possible.

那么通过传入一个实例属性试图在这里做什么是没有意义的,是不可能的。

What you could do is make startDateString static then pass it in like so: @property({ afterDate: MyClass.startDateString }).

你可以做的是使startDateString为static,然后传递给它:@property({afterDate:MyClass.startDateString})。

#2


3  

You can't access to a object property from a attribute definition.

您无法从属性定义访问对象属性。

Decorator is called when the property is defined.

定义属性时调用Decorator。

You could use getter or setter to get control when access to the property.

在访问该属性时,您可以使用getter或setter来获取控制权。

#1


7  

What you are trying to do is not possible.

你想要做的是不可能的。

Decorators get called when the class is declared and at this time there is no instance to pass into the decorator.

声明类时会调用装饰器,此时没有实例传递给装饰器。

For example, with this code:

例如,使用此代码:

class MyClass {
    startDateString: string;
    @property({ afterDate: this.startDateString })
    endDateString: string;
}
let myClass = new MyClass();
  1. MyClass is declared.
  2. 声明了MyClass。
  3. The decorators are run on MyClass. There is no instance that exists to pass in at this point and this in the decorator argument refers to the global object—not an instance.
  4. 装饰器在MyClass上运行。此时没有传入的实例,而decorator参数中的这个实例引用的是全局对象 - 而不是实例。
  5. new MyClass() is called and the instance is created. Decorators aren't called on this step. That already happened.
  6. 调用新的MyClass()并创建实例。此步骤不会调用装饰器。那已经发生了。

Take a look at the compiled JavaScript for reference:

看看编译的JavaScript以供参考:

var MyClass = (function () {
    // -- 1 --
    function MyClass() {
    }
    // -- 2 --
    __decorate([
        // see here... `this` is equal to the global object
        property({ afterDate: this.startDateString })
    ], MyClass.prototype, "endDateString", void 0);
    return MyClass;
})();
// -- 3 --
var myClass = new MyClass();

Note that using this.startDateString doesn't throw a compile error here because this is typed as any.

请注意,使用this.startDateString不会在此处引发编译错误,因为这是任何类型。

So what is trying to be done here by passing in an instance property doesn't make sense and isn't possible.

那么通过传入一个实例属性试图在这里做什么是没有意义的,是不可能的。

What you could do is make startDateString static then pass it in like so: @property({ afterDate: MyClass.startDateString }).

你可以做的是使startDateString为static,然后传递给它:@property({afterDate:MyClass.startDateString})。

#2


3  

You can't access to a object property from a attribute definition.

您无法从属性定义访问对象属性。

Decorator is called when the property is defined.

定义属性时调用Decorator。

You could use getter or setter to get control when access to the property.

在访问该属性时,您可以使用getter或setter来获取控制权。