4

我正在尝试使用 JsonSchema-Form 组件,但是在尝试创建表单时遇到了问题,在第一个下拉列表中选择一个选项后,应该会出现一个辅助下拉列表,并为用户提供不同的选项集取决于他通过 API 调用在第一个下拉菜单中选择的内容。

问题是,在分别阅读了此处此处找到的文档和一些示例之后,我仍然不知道如何参考我在第一个选项中选择的任何内容来影响第二个下拉列表。这是我现在拥有的一个例子:

应该通过 api 调用在第一个和第二个下拉列表中显示的 Jsons 信息:

Groups: [
{id: 1,
name: Group1}
{id: 2,
name: Group2}
]
User: [User1.1,User1.2,User2.1,User2.2,User3.1,User3.2, ....]

如果用户选择第一组,那么我必须使用以下 api 调用来获取用户类型,这让我得到了 USER json。

调用JSonChemaForm的组件

render(){
 return(
          <JsonSchemaForm
            schema={someSchema(GroupOptions)}
            formData={this.state.formData}
            onChange={{}}
            uiSchema={someUiSchema()}
            onError={() => {}}
            showErrorList={false}
            noHtml5Validate
            liveValidate
          > 
 )
}

架构文件内容:

export const someSchema = GroupOptions => ({
  type: 'object',
  required: [
    'groups', 'users',
  ],
  properties: {
    groups: {
      title: 'Group',
      enum: GroupOptions.map(i=> i.id),
      enumNames: GroupOptions.map(n => n.name),
    },
    users: {
      title: 'Type',
      enum: [],
      enumNames: [],
    },
  },
});

export const someUISchema = () => ({
  groups: {
    'ui:autofocus': true,
    'ui:options': {
      size: {
        lg: 15,
      },
    },
  },
  types: {
    'ui:options': {
      size: {
        lg: 15,
      },
    },
  },

});

我不太确定如何进行此操作,也不确定如何使用 Onchange 方法来做我想做的事。

4

1 回答 1

2

我为您的问题找到了解决方案。 react-jsonschema-form-layout中有一个类似的演示可以解决它。1.定义LayoutField,这是react-jsonschema-form-layout中demo的一部分。为了方便你,我把代码贴在这里。创建 layoutField.js.:

import React from 'react'
import ObjectField from 'react-jsonschema-form/lib/components/fields/ObjectField'
import { retrieveSchema } from 'react-jsonschema-form/lib/utils'
import { Col } from 'react-bootstrap'

export default class GridField extends ObjectField {
    state = { firstName: 'hasldf' }
    render() {
        const {
            uiSchema,
            errorSchema,
            idSchema,
            required,
            disabled,
            readonly,
            onBlur,
            formData
        } = this.props
        const { definitions, fields, formContext } = this.props.registry
        const { SchemaField, TitleField, DescriptionField } = fields
        const schema = retrieveSchema(this.props.schema, definitions)
        const title = (schema.title === undefined) ? '' : schema.title

        const layout = uiSchema['ui:layout']

        return (
            <fieldset>
                {title ? <TitleField
                    id={`${idSchema.$id}__title`}
                    title={title}
                    required={required}
                    formContext={formContext}/> : null}
                {schema.description ?
                    <DescriptionField
                        id={`${idSchema.$id}__description`}
                        description={schema.description}
                        formContext={formContext}/> : null}
                {
                    layout.map((row, index) => {
                        return (
                            <div className="row" key={index}>
                                {
                                    Object.keys(row).map((name, index) => {
                                        const { doShow, ...rowProps } = row[name]
                                        let style = {}
                                        if (doShow && !doShow({ formData })) {
                                            style = { display: 'none' }
                                        }
                                        if (schema.properties[name]) {
                                            return (
                                                <Col {...rowProps} key={index} style={style}>
                                                    <SchemaField
                                                        name={name}
                                                        required={this.isRequired(name)}
                                                        schema={schema.properties[name]}
                                                        uiSchema={uiSchema[name]}
                                                        errorSchema={errorSchema[name]}
                                                        idSchema={idSchema[name]}
                                                        formData={formData[name]}
                                                        onChange={this.onPropertyChange(name)}
                                                        onBlur={onBlur}
                                                        registry={this.props.registry}
                                                        disabled={disabled}
                                                        readonly={readonly}/>
                                                </Col>
                                            )
                                        } else {
                                            const { render, ...rowProps } = row[name]
                                            let UIComponent = () => null

                                            if (render) {
                                                UIComponent = render
                                            }

                                            return (
                                                <Col {...rowProps} key={index} style={style}>
                                                    <UIComponent
                                                        name={name}
                                                        formData={formData}
                                                        errorSchema={errorSchema}
                                                        uiSchema={uiSchema}
                                                        schema={schema}
                                                        registry={this.props.registry}
                                                    />
                                                </Col>
                                            )
                                        }
                                    })
                                }
                            </div>
                        )
                    })
                }</fieldset>
        )
    }
}

在文件中,您可以定义 doShow 属性来定义是否显示另一个组件。Next.在JsonChemaForm中定义isFilled函数

const isFilled = (fieldName) => ({ formData }) => (formData[fieldName] && formData[fieldName].length) ? true : false

第三,选择第一个下拉菜单后,将显示第二个下拉菜单

import LayoutField from './layoutField.js'
const  fields={
   layout: LayoutField
}
const uiSchema={
    "ui:field": 'layout',
    'ui:layout': [
        {
            groups: {
                'ui:autofocus': true,
                'ui:options': {
                   size: {
                      lg: 15,
                 },
              },
            }
        },
        {
            users: {
                'ui:options': {
                    size: {
                        lg: 15,
                    },
                },
                doShow: isFilled('groups')
            }
        }
    ]
}
...
render() {
    return (
        <div>
            <Form
                schema={schema}
                uiSchema={uiSchema}
                fields={fields}
            />
        </div>
    )
}
于 2018-10-15T14:31:35.173 回答