【问题标题】:React Admin - Create and edit in modalReact Admin - 在模态中创建和编辑
【发布时间】:2018-12-20 17:47:02
【问题描述】:

https://github.com/marmelab/react-admin/issues/850 的讨论之后,有人设法将创建/编辑表单制作成模态吗?

谢谢,

尼古拉斯

【问题讨论】:

  • 我放假回来的时候会发布一个详细的答案。同时,您可以探索此代码框:codesandbox.io/s/ypp9ljxqlj。看CommentCreate组件
  • 大声笑。我只是在看同样的东西。
  • @GildasGarcia 谢谢!您可能需要删除PostQuickCreateButton 处的CancelButton 代码,因为它不会在任何地方使用。
  • 绝对!实际上它是一个旧的沙箱,因为我弄乱了我的代码沙箱,删除了错误的沙箱,现在我必须为一篇高级的 react-admin 教程博客文章重建它。敬请期待:)
  • 刚刚更新了 codedsandbox :)

标签: modal-dialog material-ui redux-form react-admin


【解决方案1】:

我之前的答案已被删除,因为它不包含实际代码,而仅包含链接。这是一个新的,两者都有:

这是一个展示如何做到这一点的教程:https://marmelab.com/blog/2018/08/27/react-admin-tutorials-custom-forms-related-records.html

您可以在此处找到代码框:https://codesandbox.io/s/ypp9ljxqlj

例如,假设我们想在处理新评论时创建一个新帖子。你可以有一个自定义的PostReferenceInput,它会在输入旁边显示一个按钮来创建一个新的帖子:

import React, { Fragment } from 'react';
import { Field } from 'redux-form';
import { ReferenceInput, SelectInput } from 'react-admin';

import PostQuickCreateButton from './PostQuickCreateButton';

const PostReferenceInput = props => (
    <Fragment>
        <ReferenceInput {...props}>
            <SelectInput optionText="title" />
        </ReferenceInput>

        <PostQuickCreateButton />
    </Fragment>
);

export default PostReferenceInput;

然后PostQuickCreateButton 将负责显示模态/侧面板/其他内容并处理实际创建。请注意,我们直接使用 dataProvider 以便我们知道何时关闭模式:

import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';
import { change, submit, isSubmitting } from 'redux-form';
import {
    fetchEnd,
    fetchStart,
    required,
    showNotification,
    crudGetMatching,
    Button,
    SaveButton,
    SimpleForm,
    TextInput,
    LongTextInput,
    CREATE,
    REDUX_FORM_NAME
} from 'react-admin';
import IconContentAdd from '@material-ui/icons/Add';
import IconCancel from '@material-ui/icons/Cancel';
import Dialog from '@material-ui/core/Dialog';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';

import dataProvider from '../dataProvider';

class PostQuickCreateButton extends Component {
    state = {
        error: false,
        showDialog: false
    };

    handleClick = () => {
        this.setState({ showDialog: true });
    };

    handleCloseClick = () => {
        this.setState({ showDialog: false });
    };

    handleSaveClick = () => {
        const { submit } = this.props;

        // Trigger a submit of our custom quick create form
        // This is needed because our modal action buttons are oustide the form
        submit('post-quick-create');
    };

    handleSubmit = values => {
        const {
            change,
            crudGetMatching,
            fetchStart,
            fetchEnd,
            showNotification
        } = this.props;

        // Dispatch an action letting react-admin know a API call is ongoing
        fetchStart();

        // As we want to know when the new post has been created in order to close the modal, we use the
        // dataProvider directly
        dataProvider(CREATE, 'posts', { data: values })
            .then(({ data }) => {
                // Refresh the choices of the ReferenceInput to ensure our newly created post
                // always appear, even after selecting another post
                crudGetMatching(
                    'posts',
                    'comments@post_id',
                    { page: 1, perPage: 25 },
                    { field: 'id', order: 'DESC' },
                    {}
                );

                // Update the main react-admin form (in this case, the comments creation form)
                change(REDUX_FORM_NAME, 'post_id', data.id);
                this.setState({ showDialog: false });
            })
            .catch(error => {
                showNotification(error.message, 'error');
            })
            .finally(() => {
                // Dispatch an action letting react-admin know a API call has ended
                fetchEnd();
            });
    };

    render() {
        const { showDialog } = this.state;
        const { isSubmitting } = this.props;

        return (
            <Fragment>
                <Button onClick={this.handleClick} label="ra.action.create">
                    <IconContentAdd />
                </Button>
                <Dialog
                    fullWidth
                    open={showDialog}
                    onClose={this.handleCloseClick}
                    aria-label="Create post"
                >
                    <DialogTitle>Create post</DialogTitle>
                    <DialogContent>
                        <SimpleForm
                            // We override the redux-form name to avoid collision with the react-admin main form
                            form="post-quick-create"
                            resource="posts"
                            // We override the redux-form onSubmit prop to handle the submission ourselves
                            onSubmit={this.handleSubmit}
                            // We want no toolbar at all as we have our modal actions
                            toolbar={null}
                        >
                            <TextInput source="title" validate={required()} />
                            <LongTextInput
                                source="teaser"
                                validate={required()}
                            />
                        </SimpleForm>
                    </DialogContent>
                    <DialogActions>
                        <SaveButton
                            saving={isSubmitting}
                            onClick={this.handleSaveClick}
                        />
                        <Button
                            label="ra.action.cancel"
                            onClick={this.handleCloseClick}
                        >
                            <IconCancel />
                        </Button>
                    </DialogActions>
                </Dialog>
            </Fragment>
        );
    }
}

const mapStateToProps = state => ({
    isSubmitting: isSubmitting('post-quick-create')(state)
});

const mapDispatchToProps = {
    change,
    crudGetMatching,
    fetchEnd,
    fetchStart,
    showNotification,
    submit
};

export default connect(mapStateToProps, mapDispatchToProps)(
    PostQuickCreateButton
);

【讨论】:

  • 在模式中具有下拉(选择或自动完成)输入会在模式后面呈现建议弹出窗口,并且用户看不到它们。
  • 使用 mui 样式在自动完成/选择上正确设置 zindex
  • 嗨@GildasGarcia,这个示例仍然适用于react-admin 3.x 版吗?我用 react-admin 3.2.3 尝试过,但出现错误“TypeError: f.pauseValidation is not a function”
  • 不会,因为我们从 redux-form 切换到 final-form。我会尽快重写教程
  • @GildasGarcia 更新教程完成后能否提供链接?也许您可以提供一个快速的代码示例供我们同时使用? :)
猜你喜欢
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 2020-05-04
  • 1970-01-01
相关资源
最近更新 更多