首页 > 解决方案 > 用于创建 xml 文档的 Formik 表单模板

问题描述

我正在使用 Formik 库构建一个反应表单。我的目标是使用表单的输入创建一个 xml 文档。我的方法是,如果我可以使用 Formik 创建一个结构良好的 JS 对象,那么我可以编写一个函数来将这些表单字段写入一个 xml 方案。

现在我知道使用 Formik 的<FieldArray /> 组件,我可以创建嵌套对象,这可以帮助我稍后处理 xml 文件创建的父元素和子元素,但我真的需要关于如何处理对象内部的 xml 属性的帮助。属性也是表单的一部分。用户应该能够将它们作为普通表单字段输入。我正在拼命寻找解决方案。下面我介绍了所需 xml 文档和所需表单字段的方案。 在此处输入图像描述

  <creators>
   <creator>
     <creatorName nameType="Personal">Miller, Elizabeth</creatorName>
     <givenName>Elizabeth</givenName>
     <familyName>Miller</familyName>
     <nameIdentifier schemeURI="organi.org/" nameIdentifierScheme="ORC">7</nameIdentifier>
     <affiliation>DataCite</affiliation>
   </creator>
  </creators>

有人可以给我一个例子,如何创建一个<FieldArray />对创建上述计划 xml 文档有用的组件吗?

更新:非常感谢@rutherford-wonkington 的回答。

我看到您尝试通过向 JS 对象添加“值”键来解决我的属性问题。这正是我想要的。根据您的建议,稍作修改,我在下面创建了一个组件。你认为这个组件会完成交易吗?然后我可以重新编辑这篇文章并接受你的回答。

import { FieldArray, Form, Field,Formik } from "formik";
import { Button } from "@material-ui/core";




export const Creators = () => (
    <div>
        <h1>Creators</h1>
        <Formik
            initialValues={{
                creator: [
            {creatorName: {value: "Elisabeth, Miller", nameType: "Personal"}}, {givenName: 'Elisabeth'},
            {familyName: "Miller"},
            {nameIdentifier: {value:'7', schemeURI: "organi.org/", nameIdentifierScheme:"ORC"}},
            {affiliation: "Cook"}
            ]}}
            render={({ values }) => (
                <Form>
                    <FieldArray
                        name="creator"
                        render={arrayHelpers => (
                            <div>
                                {values.creator.map((creator, index) => (
                                    <div>
                                        <Field name={`creator.${index}.creatorName.value`} />
                                        <Field name={`creator.${index}.creatorName.nameType`} />
                                        <Field name={`creator.${index}.givenName`} />
                                        <Field name={`creator.${index}.familyName`} />
                                        <Field name={`creator.${index}.nameIdentifier.value`} />
                                        <Field name={`creator.${index}.nameIdentifier.schemeURI`} />
                                        <Field name={`creator.${index}.nameIdentifier.nameIdentifierScheme`} />
                                        <Field name={`creator.${index}.affiliation`} />

                                        <Button type="button" onClick={() => arrayHelpers.remove(index)}>
                                            -
                                        </Button>
                                    </div>
                                ))}
                                <Button color="primary"
                                        type="button"
                                        onClick={() => arrayHelpers.push({})}
                                >
                                    Add New
                                </Button>
                            </div>
                        )}
                    />
                    <pre>{JSON.stringify(values, null,2 )}</pre>
                </Form>
            )}
        />
    </div>
);

标签: xmlreactjsformsxml-parsingformik

解决方案


您可以像这样构造数据:

const initialValues = {
  creators: [
    {
      creatorName: {
        value: "Miller, Elizabeth",
        nameType: "Personal"
      },
      givenName: "Elizabeth",
      familyName: "Miller",
      nameIdentifier: {
        value: "7",
        schemeURI: "organi.org/",
        nameIdentifierScheme: "ORC"
      },
      affiliation: "DataCite"
    }
  ]
};

不难看出如何使用名称字段中的点表示法将每个值和选项与其自己的特定值相关联。您可以使用FieldArray映射到 creators 数组并Fields为每个值和选项生成一组,就像 Formik 文档中的这个示例一样:

<Form>
  <FieldArray
    name="friends"
    render={arrayHelpers => (
      <div>
        {values.friends.map((friend, index) => (
          <div key={index}>
            <Field name={`friends[${index}].name`} />
            <Field name={`friends.${index}.age`} /> {/* both these conventions do the same */}
            <button type="button" onClick={() => arrayHelpers.remove(index)}>
              -
            </button>
          </div>
        ))}
        <button
          type="button"
          onClick={() => arrayHelpers.push({ name: '', age: '' })}
        >
          +
        </button>
      </div>
    )}
  />
</Form>

当您将对象解析为 XML 时,只需将value其用于值,并将其他字段用作属性。


推荐阅读