当我用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_new
和age_new
),而不包含来自“ record”的title
和age
字段
这些字段在API方面给我带来很多麻烦,我想避免/从所有表单中排除它们,基本上,我只希望仅使用SimpleForm输入来发送表单输入。
我想到的解决方案很少: 1.“在提交之前更改表单值” here 2.在restProvider中处理请求
这两种解决方案都不适合我,因为我有很多这样的形式,并且restProvider代码看起来很糟糕。另外,我也不想“更改”我构建的任何表单。
请咨询。
答案 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 })),