设计表单构建器的数据库和状态突变和请求,以与 graphQL、动物数据库、nextJS 和 Apollo 做出反应

Posted

技术标签:

【中文标题】设计表单构建器的数据库和状态突变和请求,以与 graphQL、动物数据库、nextJS 和 Apollo 做出反应【英文标题】:Designing the db and state mutations and requests of a form builder in react with graphQL, faunaDB, nextJS & Apollo 【发布时间】:2021-05-29 04:39:14 【问题描述】:

我正在开发下一个 JS、React、Apollo、graphQL、animalDB 应用程序。我正在尝试构建表单构建器如何通过graphQL处理它对动物群的突变。我能够从操场上运行突变,并且可以从前端查询并构建我的表单。这里看到的互动https://www.loom.com/share/7f7d1e1231d445f2be6b5db2c81239b6

现在我很确定我可以弄清楚如何在前端运行突变,我关心的是什么时候运行它?请参阅我有以下代码。它查询动物数据库,并从状态(由查询填充)输出表单输入元素(当前只是文本类型),并允许您向状态添加新的表单输入类型,从而导致重新渲染并显示新的表单输入元素。这一切都很好。

import  useQuery, gql  from "@apollo/client";
import  useEffect, useState  from "react";
import  v4 as uuidv4  from "uuid";

const INPUT_VALUES = gql`
  query GetInputValues 
    allFormInputVals 
      data 
        name
        _id
        type
      
    
  
`;

const Home = () => 
  const  loading, error, data  = useQuery(INPUT_VALUES);

  const [formState, setFormState] = useState(undefined);

  useEffect(() => 
    setFormState(data?.allFormInputVals?.data);
  , [data]);

  const addInput = () => 
    const blanktext = 
      __typename: "FormInputType",
      name: "Product Image",
      _id: uuidv4(),
      type: "text",
    ;
    console.log(formState);
    setFormState([...formState,  ...blanktext ]);
  ;

  if (loading) return <p>Loading...</p>;

  if (error) return <p>Error: error.message</p>;

  return (
    <>
      <form>
        <input type="button" value="Add Form Input" onClick=addInput />
        formState?.map((val, idx) => 
          const nameId = `name-$idx`;
          const typeId = `type-$idx`;
          return (
            <div key=val._id>
              val.type === "text" && (
                <>
                  <label htmlFor=nameId>`Name #$idx + 1`</label>

                  <input
                    type="text"
                    name=nameId
                    id=nameId
                    className=val.type
                  />
                  <label htmlFor=typeId>`Type #$idx + 1`</label>

                  <select name=typeId id=typeId className=val.type>
                    data.allFormInputVals.data.map((item) => 
                      return (
                        <option key=item._id value=item.type>
                          item.type
                        </option>
                      );
                    )
                  </select>
                </>
              )
            </div>
          );
        )
      </form>
    </>
  );
;

export default Home;

然而,我在操场上的变异选项似乎仅限于一次只添加一个所谓的文档,即一个对象。如果我控制台记录我想要添加到数据库的状态,它看起来如下所示。现在我可以在操场上做一个突变,在那里我可以添加这些对象之一。但我希望能够一次添加所有这些。在保存操作上。我想这样做是因为我不想对表单的每个添加都运行请求,我想使用反应状态来处理表单直到最后,然后执行我的数据库请求。

[
   
      "__typename":"FormInputVal",
      "name":"name",
      "_id":"291541872966369805",
      "type":"text"
   ,
   
      "__typename":"FormInputVal",
      "name":"name",
      "_id":"291541888089981453",
      "type":"text"
   ,
   
      "__typename":"FormInputVal",
      "name":"Product Image",
      "_id":"255f95e0-bff1-4e75-81fc-d6f3f9a72446",
      "type":"text"
   
]

现在我创建了一个 graphQL 模式,它有用户,可以有很多表单,表单可以有很多输入。看起来是这样。 @relation 指令是针对动物区系的。除了我一直提到的突变问题之外,它按我的预期工作。

type Form 
  name: String!
  index: Int!
  user: User
  formInputVals: [FormInputVal!] @relation


type FormInputVal 
  name: String!
  index: Int!
  type: String!
  formRoot: Form!


type User 
  name: String!
  email: String!
  password: String!
  forms: [Form] @relation


type Query 
  allForms: [Form!]
  allUsers: [User!]
  allFormInputVals: [FormInputVal!]

请参阅我可以使用以下内容对数据库进行变异。我选择一个特定的表单并添加一个输入,从而导致前端重新呈现并显示表单输入。这一切都很好。这是该类型的示例变化。

mutation
  createFormInputVal(data:
    formRoot:connect:"291541554941657608",name:"name",type:"text",index:0)
    name
    type
    index
    formRoot
      name
    
  

但问题的根源就在这里。

我想获取由 react 创建的状态并将其添加到一个名为 formInputVal 的动物群数据库集合中,graphql 架构映射到 db 集合。

我与 Fauna 支持人员进行了交谈,他们提到了一个 @resolver 指令,我可以在其中运行一个 DB 函数并一次添加多个文档(对象),到目前为止,floraDB 的 lambda 函数语法超出了我的理解。他们提到这篇文章是为了函数https://docs.fauna.com/fauna/current/tutorials/ecommerce#function,这篇文章是为了解析器https://forums.fauna.com/t/placing-an-index-on-a-field-in-an-embedded-type/778/4

让我们澄清一下,

我接近这个了吗?我愿意更改架构。如果您想使用替代方法或相同方法解决此问题,但缺少我不明白的部分,您会怎么做。

为什么我不能只将一组对象传递给突变以获得正确的 formID,并且它会在一个查询中将那么多文档添加到集合中。有没有什么通用的做法可以创建这样的生成形式。

好的,提前感谢您的帮助。

更新:

我尝试了以下突变,但它不起作用。它带有以下错误Unknown argument 'formInputVal' on field 'createFormInputVal' of type 'Mutation'

const ADD_INPUT_VALUES = gql`
  mutation AddInputValues($formInputVal: FormInputValInput!) 
    createFormInputVal(formInputVal: $formInputVal) 
      name
    
  
`;

const [createFormInputVal,  data: createInputData ] = useMutation(
    ADD_INPUT_VALUES
  );

...
<form
        onSubmit=async (e) => 
          e.preventDefault();
          const res = await createFormInputVal(
            variables: formState,
          ).catch(console.error);
          console.log(res);
        
      >
...

【问题讨论】:

您从未听说过输入类型,对吧? graphql.org/learn/schema/#input-types 不,我没有听说过这些,看起来这可能是我正在寻找的东西,将不得不查看更多示例以了解如何使用它们,谢谢。 我仍然对如何使用输入类型编写突变有点困惑,动物区系说输入类型是自动生成的并在突变中使用,但不确定如何将对象传递给它.任何想法docs.fauna.com/fauna/current/api/graphql/input 我在操场上的文档FormInputValInput 中看到了这种输入类型,但不确定如何在突变中使用它? 什么都没读...但是查看类型定义可能你应该使用createForm,而不是createFormInputVal 【参考方案1】:

如果这里问题的根源是一次变异或创建多个文档,我认为它在这里重复:

https://***.com/a/68930202/534056

需要注意的几点:

为您的自定义输入选择一个不等于 [type name] + Input 的名称。这是 Fauna 用于自动生成的 CRUD 操作,如果您自己定义一个,它将覆盖生成的。例如,给定类型Form,Fauna 将生成一个名为FormInput 的输入类型,因此不要将其用于自定义类型。

如果要传递数据数组作为输入,请将参数指定为 List 类型(放在方括号中)。

如果您要更新某些文档,则需要传入 ID。 GraphQL API 隐藏了 Refs 周围的一些细节,因此在您的 UDF 中,您需要根据 ID 重构 ref。

【讨论】:

以上是关于设计表单构建器的数据库和状态突变和请求,以与 graphQL、动物数据库、nextJS 和 Apollo 做出反应的主要内容,如果未能解决你的问题,请参考以下文章

未使用 Vuex 中的计算属性注册突变

20145339《信息安全系统设计基础》第十一周学习总结

如何将对象设置为表单值以与 Material UI 做出反应?

20145216史婧瑶《信息安全系统设计基础》第十一周学习总结

2018-2019-1 20165333 《信息安全系统设计基础》第七周学习总结

登录表单 React Native 和 Apollo