react-admin 从 redux-form 中排除 "record"

react-admin exclude "record" from the redux-form

我在使用 react-admin 发送 SimpleForm(编辑)请求时遇到问题。 该请求包含的参数比我在表单字段中的参数多。

例如我有表格:

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

它只包含 2 个字段,但是当我单击 "save" 时,请求包含更多字段。 我知道这些字段来自 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),而没有出现的 titleage 字段来自 "record".

这些字段让我在 API 方面遇到很多麻烦,我想从所有表单中 avoid/exclude 它们,基本上我只想发送带有 SimpleForm 输入的表单输入.

我想到的解决方案很少: 1. "Altering the Form Values before Submitting" here 2.在restProvider

中操作请求

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

请多多指教。

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

我不确定提供者在更改后会不会看起来很糟糕:您所要做的就是更改 UPDATE 动词。默认情况下,它看起来像(对于简单的休息提供者):

            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 = 'PATCH';
-               options.body = JSON.stringify(params.data);
+               options.body = JSON.stringify(diff(params.data, param.previousData));
                break;

其中diff可以写成:

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

要有选择地发送刚刚更改的字段,请使用这样的 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 })),