用于 xml 文档创建的 Formik 表单模板

Formik form template for xml document creation

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

现在我知道使用 Formik 的 <FieldArray /> component,我可以创建嵌套对象,这可以帮助我稍后处理 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 对象添加 'value' 键来解决我的属性问题。这正是我要找的。根据您的建议,稍作修改,我在下面创建了一个组件。你认为这个组件会完成交易吗?然后我可以重新编辑这个 post 并接受你的回答。

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

您可以像这样构造您的数据:

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 作为值,并将其他字段应用为属性。