react-admin从redux表单中排除“记录”

时间:2019-03-05 19:22:41

标签: react-admin

当我用react-admin发送SimpleForm(edit)请求时,我遇到了一个问题。 该请求包含的参数比我在表单字段中拥有的参数还要多。

例如,我有表格:

<Edit {...props}>
    <SimpleForm>
        <TextInput source="title_new" />
        <TextInput source="age_new" />
    </SimpleForm>
</Edit>

它仅包含2个字段,但是当我单击“保存”时,请求包含了更多字段。 我知道这些字段来自GET_ONE请求,这些请求填充了数据库中的数据。

GET_ONE:

{
title: 'title',
title_new: 'title-new',
age: 'age',
age_new: 'age-new',
}

更新请求UPDATE:

{
title: 'title',
title_new: 'title-new',
age: 'age',
age_new: 'age-new',
}

我希望UPDATE仅包含表单字段(title_newage_new),而不包含来自“ record”的titleage字段

这些字段在API方面给我带来很多麻烦,我想避免/从所有表单中排除它们,基本上,我只希望仅使用SimpleForm输入来发送表单输入。

我想到的解决方案很少: 1.“在提交之前更改表单值” here 2.在restProvider中处理请求

这两种解决方案都不适合我,因为我有很多这样的形式,并且restProvider代码看起来很糟糕。另外,我也不想“更改”我构建的任何表单。

请咨询。

2 个答案:

答案 0 :(得分:2)

这是react-admin的工作方式。如果您希望UPDATE dataProvider动词仅发布更改字段(并且可能发送PATCH而不是POST),则必须在dataProvider中进行。

我不确定更改后提供程序的外观是否很糟糕:您要做的就是更改UPDATE动词。默认情况下,它看起来像(对于简单的rest提供程序):

            case UPDATE:
                url = `${apiUrl}/${resource}/${params.id}`;
                options.method = 'PUT';
                options.body = JSON.stringify(params.data);
                break;

您只需要这样更新即可:

            case UPDATE:
                url = `${apiUrl}/${resource}/${params.id}`;
                options.method = 'PUT';
-               options.body = JSON.stringify(params.data);
+               options.body = JSON.stringify(diff(params.data, param.previousData));
                break;

diff可以写为:

consy diff = (previous, current) => lodash.pickBy(current, (v, k) => previous[k] !== v);

答案 1 :(得分:0)

要选择性地发送刚刚更改的字段,请使用 diff 函数,如下所示:

// in diff.js
import { transform, isEqual, isObject } from 'lodash';

/**
 * Deep diff between two object, using lodash
 * @param  {Object} object Object compared
 * @param  {Object} base   Object to compare with
 * @return {Object}        Return a new object who represent the diff
 */
const diff = (object, base) => {
  return transform(object, (result, value, key) => {
    if (!isEqual(value, base[key])) {
      result[key] =
        isObject(value) && isObject(base[key]) ? diff(value, base[key]) : value;
    }
  });
};

export default diff;

然后:

// in dataProvider.js
update: (resource, params) =>
    httpClient(`${apiUrl}/${resource}/${params.id}`, {
      method: 'PATCH',
      body: JSON.stringify(diff(params.data, params.previousData)),
    }).then(({ json }) => ({ data: json })),