cherry-pick: Action组件required属性不生效问题 #4560 (#4570)

This commit is contained in:
RUNZE LU 2022-06-09 17:17:08 +08:00 committed by GitHub
parent e1af793147
commit 197682b2e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 74 deletions

View File

@ -960,7 +960,12 @@ export default class Form extends React.Component<FormProps, object> {
data = store.data;
}
if (Array.isArray(action.required) && action.required.length) {
return store.validateFields(action.required).then(async result => {
const fields = action.required.map(item => ({
name: item,
rules: {isRequired: true}
}));
return store.validateFields(fields).then(async result => {
if (!result) {
const dispatcher = await dispatchEvent(
'validateError',

View File

@ -17,6 +17,7 @@ import {
} from '../utils/helper';
import isEqual from 'lodash/isEqual';
import flatten from 'lodash/flatten';
import find from 'lodash/find';
import {filter} from '../utils/tpl';
import {normalizeApiResponseData} from '../utils/api';
@ -537,20 +538,27 @@ export const FormStore = ServiceStore.named('FormStore')
return self.valid;
});
const validateFields: (fields: Array<string>) => Promise<boolean> = flow(
function* validateFields(fields: Array<string>) {
const validateFields: (
fields: Array<string | {name: string; rules: {[propName: string]: any}}>
) => Promise<boolean> = flow(function* validateFields(
fields: Array<string | {name: string; rules: {[propName: string]: any}}>
) {
const items = self.items.concat();
const normalizedfields = fields.map(field =>
typeof field === 'string' ? {name: field, rules: {}} : field
);
let result: Array<boolean> = [];
for (let i = 0, len = items.length; i < len; i++) {
let item = items[i] as IFormItemStore;
const field = find(normalizedfields, field => field.name === item.name);
if (~fields.indexOf(item.name)) {
result.push(yield item.validate(self.data));
if (field) {
result.push(yield item.validate(self.data, undefined, field.rules));
}
}
return result.every(item => item);
}
);
});
function clearErrors() {
const items = self.items.concat();

View File

@ -317,8 +317,19 @@ export const FormItemStore = StoreNode.named('FormItemStore')
}
let validateCancel: Function | null = null;
const validate: (data: Object, hook?: any) => Promise<boolean> = flow(
function* validate(data: Object, hook?: any) {
const validate: (
data: Object,
hook?: any,
/**
* customRules主要是为了支持action.require的验证方式
* action实现不同的校验规则
*/
customRules?: {[propName: string]: any}
) => Promise<boolean> = flow(function* validate(
data: Object,
hook?: any,
customRules?: {[propName: string]: any}
) {
if (self.validating && !isEffectiveApi(self.validateApi, data)) {
return self.valid;
}
@ -330,7 +341,13 @@ export const FormItemStore = StoreNode.named('FormItemStore')
}
addError(
doValidate(self.tmpValue, data, self.rules, self.messages, self.__)
doValidate(
self.tmpValue,
data,
customRules ? str2rules(customRules) : self.rules,
self.messages,
self.__
)
);
if (!self.errors.length && isEffectiveApi(self.validateApi, data)) {
@ -344,17 +361,14 @@ export const FormItemStore = StoreNode.named('FormItemStore')
/** 如果配置validateApi需要将用户最新输入同步到数据域内 */
createObject(data, {[self.name]: self.tmpValue}),
{
cancelExecutor: (executor: Function) =>
(validateCancel = executor)
cancelExecutor: (executor: Function) => (validateCancel = executor)
}
);
validateCancel = null;
if (!json.ok && json.status === 422 && json.errors) {
addError(
String(
json.errors || json.msg || `表单项「${self.name}」校验失败`
)
String(json.errors || json.msg || `表单项「${self.name}」校验失败`)
);
}
}
@ -379,8 +393,7 @@ export const FormItemStore = StoreNode.named('FormItemStore')
self.validating = false;
return self.valid;
}
);
});
function setError(msg: string | Array<string>, tag: string = 'builtin') {
clearError();