最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS TS decorator to conditionally prevent method execution - Stack Overflow

programmeradmin1浏览0评论

I would like to write a method decorator that conditionally prevents the execution the method or to replace the method with some other procedure. In particular I want different behavior based on when it is called on the client or on the server:

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)
    }
}

I would like to write a method decorator that conditionally prevents the execution the method or to replace the method with some other procedure. In particular I want different behavior based on when it is called on the client or on the server:

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)
    }
}
Share Improve this question asked Dec 3, 2017 at 16:55 ChrisChris 14.2k23 gold badges93 silver badges181 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 22

1. Conceptual Overview

ES2016 Method Decorators are functions that have 3 parameters:

  • target — either the prototype of the class (if the method being decorated is an instance method) or the constructor of the class (if the method being decorated is static).
  • name — the name of the method being decorated.
  • descriptor — the [descriptor object][1] of the method being decorated.

A decorator can decorate (or enhance) a method by wrapping the existing method around a new function that does more (or fewer) things than the original function.

2. Fixing/Improving the Question's Code

With this in mind, serverMethod should wrap the descriptor.value (which contains the method that we want to decorate) around a new function that checks whether we are in the client or server:

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);
  }
}

It's important not to forget the ...args, so that the arguments passed to your methods will also be used by the decorated method via method.apply.

3. Further reading

  • JS Decorator Design
  • JS Spec Proposal
  • Method Decorators in TS
发布评论

评论列表(0)

  1. 暂无评论