1

所以我觉得我的问题很可能是关于类的 JS 语法问题,但我的问题与用于在 GraphQL 中创建自定义指令的类this直接相关。graphql-toolsSchemaDirectiveVisitor

一点上下文:在 GraphQL 中创建自定义指令时,一种方法是扩展 graphql-tools 提供的 SchemaDirectiveVisitor 类,并覆盖它们的任何默认方法,这些方法可以应用于 gql 模式的不同位置。更多细节可以在这里看到

在我的具体情况下,我使用该方法visitInputFieldDefinition是因为我想添加一些自定义逻辑来验证用户是否有权编辑特定字段。主要问题visitInputFieldDefinition是它似乎只在构建服务器时触发,因为它没有解析器功能。同时,其他方法,例如visitFieldDefinition确实有一个resolve()函数,每次有这个指令的新请求时都会触发。

visitInputFieldDefinition我试图做的是在读取我的 gql 模式之后调用服务器启动时将一些数据存储在数组中。我可以将一些数据保存在类外部的数组中,然后在我的 resolve() 函数中使用该数据来确定是继续还是返回错误。我能够做到这一点并且它有效,但我的问题实际上是关于如何获得相同的行为,但以某种方式将这些数据存储在我的类内的 var 中,而不是类外的全局变量中

所以我的代码,简化后,看起来像这样

//variable outside my class where i store in memory some data from class
let outsideVar = []

class RestrictFieldsDirective extends SchemaDirectiveVisitor {
    visitFieldDefinition(field) {
        const originalResolve = field.resolve || defaultFieldResolver;

        field.resolve = async function(...args){
            //Do Stuff here with the stored array
            // return error or apply the resolver depending on data in array
            if(outsideVar) //more complicated checks on data
               return new ApolloError()

            return resolve.apply()
        }
    }

    visitInputFieldDefinition(field){
        // Do stuff here to store data provided on application build when this method gets 
        called
        outsideVar.push(someData)

    }
}

正如我所提到的,这种方法对我来说效果很好,但我不喜欢我在类外有一个全局变量的事实,而我想把它放在里面。我试图将它存储在类中的变量中,甚至存储在类中的另一个方法中,但我有两个问题

  1. 该类在启动服务器时被多次调用,因此即使我设法在构造函数级别将数据存储在 var 中,它也不会通过多次调用持续存在,如果constructor()我包含类似的东西,它总是会被重置this.myVar = []

  2. 我似乎无法访问函数this内部field.resolve(),我不知道如何授予它访问类的权限,this以便我可以调用另一个方法或类 var,例如this.myVar

问题主要是关于最佳实践,可能避免使用外部全局变量的可能改进,或者根本没有办法做到这一点,这种方法可以被认为是“正确的”。

谢谢阅读!任何讨论都是受欢迎和有用的!

4

1 回答 1

0

今天了解到,类的构造函数构造的对象的原型就是类本身。因此,一些恶作剧Object.getPrototypeOf让我们存储了一个可用于类的所有实例的静态属性:

class Thing {
  constructor(){
    // If we need to initialize the value the first time we ever make a Thing object
    Object.getPrototypeOf(this).staticProp 
      = Object.getPrototypeOf(this).staticProp || 0;
  }
  setStaticProp(val){
    Object.getPrototypeOf(this).staticProp = val;
  }
  getStaticProp() {
    return Object.getPrototypeOf(this).staticProp;
  }
}

const thing1 = new Thing();
const thing2 = new Thing();

console.log(thing1.getStaticProp())

thing1.setStaticProp(42);

console.log(thing2.getStaticProp());

FWIW,适当的静态字段即将出现在 JavaScript 中,但 Safari 尚不支持它们,这使得它们在现阶段对大多数人来说很难卖。

于 2020-07-02T01:36:43.777 回答