ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.02k stars 1.28k forks source link

🐛[BUG] ProFormList下的FormItem设置Preserve={false} 导致复制出的新行将失去数值 #8208

Open HAOYI99 opened 1 month ago

HAOYI99 commented 1 month ago

提问前先看看:

https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md

🐛 bug 描述

ProFormList的children只要set了preserve={false},copy此行就会导致新增的行数据被删

📷 复现步骤

复制前 image 复制后的结果 image

🏞 期望结果

formItem不被render时候数据可以自动清理,并且copy该行也能保留数据

💻 复现代码

<ProFormList name='full' key={'full'}
        actionRef={printerStatusActionRef}
        alwaysShowItemLabel min={1}
        initialValue={[{ printerStatus: PrinterStatus.idle }]}
        creatorRecord={{ printerStatus: PrinterStatus.idle, duration: undefined }}
        creatorButtonProps={{ creatorButtonText: 'Next Printer Status' }}
        itemRender={(dom, listMeta) => (
            <ProCard
                bordered
                title={
                    <Space direction='horizontal'>
                        <>Sequence {listMeta.index + 1}</>
                        <ProFormText name='sequenceTitle'
                            width={'sm'} noStyle
                            normalize={(value) => value.toUpperCase()} />
                        <CustomTag content='PENDING' status={SequenceStatus.PENDING} />
                    </Space>
                }
                extra={
                    <Space>
                        <Button icon={<DownOutlined />} onClick={() => {
                            printerStatusActionRef.current?.move(listMeta.index, listMeta.index + 1)
                        }} disabled={listMeta.fields.length === 1 || listMeta.index + 1 === listMeta.fields.length} />
                        <Button icon={<UpOutlined />} onClick={() => {
                            printerStatusActionRef.current?.move(listMeta.index, listMeta.index - 1)
                        }} disabled={listMeta.fields.length === 1 || listMeta.index === 0} />
                        <Button icon={<CopyOutlined />} type='primary'
                            onClick={() => {
                                const data = printerStatusActionRef.current?.get(listMeta.index)
                                const { sequenceTitle, ...newData } = data; // remove sequenceTitle
                                listMeta.operation.add(newData, listMeta.index + 1)
                            }} />
                        {listMeta.fields.length > 1 &&
                            <Button icon={<DeleteOutlined />}
                                type='primary' danger
                                onClick={() => {
                                    listMeta.operation.remove(listMeta.index)
                                }} />}
                    </Space>
                }
                style={{
                    marginBlockEnd: 8,
                    border: '2px solid rgba(5, 5, 5, 0.1)',
                    width: 1091
                }}
                bodyStyle={{ paddingBlockEnd: 0 }}
            >
                <Space>
                    {dom.listDom}
                </Space>
            </ProCard>
        )}
    >
        {(_, rowIndex: number) => {
            return (
                <ProFormGroup>
                    <ProFormSelect name='printerStatus'
                        label='Printer Status'
                        allowClear={false}
                        width={'sm'}
                        options={[
                            { label: 'BOOTING', value: PrinterStatus.booting },
                            { label: 'WAITING FOR PERIPHERALS', value: PrinterStatus.waiting_for_peripherals },
                            { label: 'IDLE', value: PrinterStatus.idle, },
                            { label: 'PRINTING', value: PrinterStatus.printing },
                            { label: 'ERROR', value: PrinterStatus.error },
                            { label: 'MAINTENANCE', value: PrinterStatus.maintenance },
                            { label: 'OFFLINE', value: PrinterStatus.offline },
                        ]}
                        onChange={() => {
                            listFormRef.current?.setFieldValue(['full', rowIndex, 'sequenceTitle'], undefined)
                        }} />
                    <ProFormDependency name={['printerStatus']}>
                        {({ printerStatus }) => {
                            switch (printerStatus) {
                                case PrinterStatus.printing:
                                    return <>
                                        <Space size={35}>
                                            <ProFormText name='jobName'
                                                label='Job Name'
                                                width={'sm'}
                                                rules={[
                                                    { required: true }
                                                ]}
                                                normalize={(value) => value.toUpperCase()}
                                            />
                                            <ProFormSelect name='jobResult'
                                                label='Job Result'
                                                width={'sm'}
                                                rules={[{ required: true }]}
                                                options={[
                                                    { label: 'ABORTED', value: JobResult.aborted },
                                                    { label: 'FAILED', value: JobResult.failed },
                                                    { label: 'FINISHED', value: JobResult.finished },
                                                ]} />
                                        </Space>
                                        // 一段很长的代码
                                                                        </>
                                default:
                                    return <FormDurationPicker />
                            }
                        }}
                    </ProFormDependency>
                </ProFormGroup>
            );
        }}
    </ProFormList>

FormDurationPicker 里设了 preserve false

const FormDurationPicker = () => {
    const durationFormat = "HH[h] mm[m] ss[s]";
    const defaultFormat = "YYYY-MM-DD HH:mm:ss";
    const outputFormat = "HH,mm,ss";

    return <ProFormTimePicker name="duration"
        preserve={false}
        label="Duration"
        width={'sm'}
        fieldProps={{
            showNow: false,
            secondStep: 10,
            minuteStep: 5,
            needConfirm: false,
            format: durationFormat
        }}
        rules={[
            { required: true, message: 'Please select Duration' }
        ]}
        transform={(value: any) => {
            // to handle value is different format
            let result = dayjs(value, [durationFormat, defaultFormat], true)
            return result.format(outputFormat)
        }} />;
}

© 版本信息

"@ant-design/pro-components": "^2.6.30",
"antd": "^5.14.2",

🚑 其他信息