如何在自定义指令上触发 visitInputObject 方法?

Posted

技术标签:

【中文标题】如何在自定义指令上触发 visitInputObject 方法?【英文标题】:How to trigger visitInputObject method on custom directive? 【发布时间】:2020-06-16 10:30:28 【问题描述】:

我正在构建一个自定义指令,希望在其中验证整个输入对象。我在SchemaDirectiveVisitor 扩展类上使用INPUT_OBJECT 类型和visitInputObject 方法。

每次我使用输入类型运行突变时,visitInputObject 都不会运行。 我使用了其他类型/方法,例如 visitObjectvisitFieldDefinition,它们运行良好。但是当尝试使用输入类型和方法时,它们不会触发。

我已阅读我能找到的所有可用文档。这还不支持吗?

一些上下文代码(不是实际的):

directive @validateThis on INPUT_OBJECT

input MyInputType @validateThis 
  id: ID
  someField: String

type Mutation 
  someMutation(myInput: MyInputType!): SomeType

class ValidateThisDirective extends SchemaDirectiveVisitor 
  visitInputObject(type) 
    console.log('Not triggering');
  

【问题讨论】:

【参考方案1】:

SchemaDirectiveVisitor 的所有访问方法都是同时运行的——在构建模式时。这包括visitFieldDefinitionvisitFieldDefinition。不同的是,我们在使用visitFieldDefinition的时候,经常会修改访问字段的resolve函数。执行过程中调用的就是这个函数。

您使用每个访问方法来修改相应的架构元素。您可以使用visitInputObject 修改输入对象,例如从中添加或删除字段。您不能使用它来修改输出对象字段的解析逻辑。你应该使用visitFieldDefinition

visitFieldDefinition(field, details) 
const  resolve = defaultFieldResolver  = field
  field.resolve = async function (parent, args, context, info) 
    Object.keys(args).forEach(argName => 
      const argDefinition = field.args.find(a => a.name === argName)
      // Note: you may have to "unwrap" the type if it's a list or non-null
      const argType = argDefinition.type
      if (argType.name === 'InputTypeToValidate') 
        const argValue = args[argName]
        // validate here
       
    )    

    return resolve.apply(this, [parent, args, context, info]);
  

【讨论】:

感谢您的回复。所以输入类型字段似乎没有解析方法?那么我如何对整个输入对象进行验证呢?使用visitObject,它允许我编辑字段的解析方法,然后从我传递的解析方法的第一个参数中获取整个类型对象字段值。 是的,只有字段被解析——解析器被执行以生成响应中返回的值。输入的解析器没有意义——它们的值已经提供。就像我说的,您需要使用visitFieldDefinition(或visitObject)并修改解析器逻辑以包含验证逻辑。如果您只想对特定类型的参数进行验证,您可以检查字段对象以确定其参数的类型。 对,有道理。我被卡住的部分是我并没有试图在它的出路时验证它,而是在它从输入的路上验证它。据我所知,visitObject 用于传出数据。我在想可能有一种方便的方式来验证方式,类似于它在出路时的方式,但听起来你可以做的唯一验证是类型检查,最多类型检查针对单个字段的自定义标量.感谢您的澄清! @FunToCodejavascript 也许我解释得不够充分。您可以在运行解析器代码之前进行验证。我用一个粗略的例子编辑了这个问题。顺便说一句,您可以使用自定义标量,但通常最好将验证逻辑放在业务层中,而不是 API 层的一部分——这样更可重用。 哦,我误会了。想到代码可以运行时,数据已经在我的数据库中,但如果我在field.resolve 中验证并停止它,它实际上会阻止突变解析器启动。我已经把它写下来了,感谢您一直以来的帮助,我为吸收而道歉。我很高兴能使用它。

以上是关于如何在自定义指令上触发 visitInputObject 方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义元素或按钮小部件上触发事件?

onItemClickListener 未在自定义 ArrayAdapter 上触发

如何在自定义 UICollectionView 的旋转后触发 drawrect?

如何在自定义用户控件上创建单击事件?

如何使用 ControlValueAccessor Angular 在自定义输入中使用指令

如何在自定义指令中处理 ng-repeat 子元素?