JS TS装饰器有条件地阻止方法执行

Chr*_*ris 9 javascript decorator typescript

我想编写一个方法装饰器,有条件地阻止执行该方法或用其他一些过程替换该方法.特别是我希望基于在客户端或服务器上调用它时的不同行为:

function serverMethod(target) {
    if(Meteor.isClient) {
        // call server method to delete a user
        // prevent execution of decorated method
    }
}

class User {
    @serverMethod
    delete() {
        UserCollection.delete(this.id)
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*tos 10

ES2016方法装饰的功能有3个参数:

  • target- 类的原型(如果正在装饰的方法是实例方法)或类的构造函数(如果正在装饰的方法是静态的).
  • name - 正在装饰的方法的名称.
  • descriptor- 正在装饰的方法的描述符对象.

装饰器可以通过将现有方法包装在比原始函数更多(或更少)的新函数中来装饰(或增强)方法.

考虑到这一点,serverMethod应该descriptor.value围绕一个检查我们是否在客户端或服务器中的新函数包装(包含我们想要装饰的方法):

function serverMethod(target: any, name: string, descriptor: PropertyDescriptor) {

    const method = descriptor.value; // references the method being decorated

    descriptor.value = function(...args) {

        if(Meteor.isClient) {
            return; // exit the function
        } 

        // This part will run when Meteor.isClient == false
        method.apply(this, args);
    };
}

class User {
    @serverMethod
    delete() {
        UserCollection.delete(this.id)
    }
}
Run Code Online (Sandbox Code Playgroud)

重要的是不要忘记...args,以便传递给您的方法的参数也将由装饰方法使用method.apply.

进一步阅读: