当前位置: 首页 > 知识库问答 >
问题:

在react with graphQL、faunaDB、nextJS中设计表单生成器的db和状态突变和请求

江仲渊
2023-03-14

我正在开发下一个JS、React、Apollo、graphQL、faunaDB应用程序。我正在尝试构建一个表单生成器如何通过graphQL处理其对动物群的突变。我可以在操场上运行突变,可以从前端查询并构建我的表单。此处显示的交互https://www.loom.com/share/7f7d1e1231d445f2be6b5db2c81239b6

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

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;

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

[
   {
      "__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指令是针对faunaDB的。除了我提到的这个突变问题之外,它的工作方式是我所期望的。

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!]
}

请看,我可以使用以下命令对DB进行变异。在这里,我选择一个特定的表单并添加一个输入,从而导致前端的重排并显示表单输入。这一切都很好。这是该类型的一个示例。

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

但问题的根源就在这里。

我想采取由反应创建的状态并将其添加到名为formInputVal的faunaDB集合中,图形ql模式映射到db集合。

我与Fauna支持人员进行了交谈,他们提到了一个@resolver指令,在该指令中,我可以运行一个DB函数并一次添加多个文档(对象),到目前为止,faunaDB的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的变体,而它在一个查询中将那么多文档添加到集合中。创造这样一种生成形式有什么一般的做法吗。

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

更新:

我尝试了以下突变,但它不起作用。它在类型为“突变”的字段“createFormInputVal”上拖运时出现以下错误未知参数“formInputVal”

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


共有1个答案

潘哲
2023-03-14
匿名用户

如果这里问题的根源是同时更改或创建多个文档,我认为它在这里重复了:

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

需要注意的几件事:

>

  • 为自定义输入选择一个不等于输入的名称。这是Fauna用于自动生成CRUD操作的内容,如果您自己定义一个CRUD操作,它将覆盖生成的CRUD操作。例如,给定类型<代码>表单,Fauna将生成名为<代码>表单输入的输入类型,因此不要将其用于自定义类型。

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

    如果要更新某些文档,则需要传入ID。GraphQL API隐藏了有关引用的一些详细信息,因此在UDF中,需要从ID重建引用。

  •  类似资料:
    • 我使用Apollo 2.0管理graphQL API调用,并处理react应用程序的全局状态。 我试图创建一个登录屏幕,用户在其中输入用户名和密码,这将发送到我的API进行身份验证,成功后,我想将isLoggedIn的全局状态设置为true。 到目前为止,我能够使用一个使用客户声明的突变来设置全局状态,因此它只与局部状态有关。我有另一个变种,它进行graphQL API调用,验证用户名/密码,然后

    • 问题内容: 我需要知道如何让NetBeans使用快捷方式生成getter和setter。 问题答案: 将光标放在班级内部,然后按+ 并从上下文菜单中选择。

    • 问题内容: 我正在尝试构建一种表单生成器,该表单生成器将允许我以灵活的方式定义,显示和存储“测试”。即,允许用户通过网络界面创建一种新型的测试/表单(“分组”)并定义一组将在表单上显示的字段(任何类型的字段,包括日期,文本,广播,复选框等)。我还需要一个结果表,该表将存储保存在每个表单/测试中的值。 作为一个不足的示例,到目前为止,我有以下3个表: 上面的问题-如果没有其他问题-我不确定如何动态显

    • 问题内容: 我有一个Webapp,允许用户创建自己的字段,以供以后使用表单呈现。 我有一个像这样的Formfield模型: 我用来代表字段的类型,无论是哪种类型(复选框,输入,以后都会有更多)。 如你所见,每个字段都有一个form_id的FK。 我正在尝试为给定的form_id生成动态表单。问题是我需要确定要为每个Formfield呈现的字段的类型。因此,我还需要在某个时候处理字段类型。 我想一个

    • 我试图重新创建本博客文章中描述的apache beam管道的一个简单示例,该示例使用了状态和计时器。 以下是从博客中复制粘贴的Enrich DoFn: 下面是我用来测试enrich: 下面是我的窗口函数: 博客文章没有具体提到它使用的窗口化策略。这会是问题所在吗?我还尝试使用作为窗口触发器,但得到相同的错误: 很抱歉这篇文章太长了,任何帮助都将不胜感激。

    • 我在从网站获取数据时遇到问题(https://avito.ru)在本地MacBook Air上使用标准golang http库-禁止im获取状态403。从浏览器(使用禁用的JavaScript)打开该站点没有问题,使用标准Curl函数(Curl-v)获取数据也没有问题https://www.avito.ru/moscow)-一直处于状态200。 有一个Golang代码: 有两张照片: 有Curl-