Skip to content

Commit

Permalink
fix: Action组件required属性不生效问题 (#4560)
Browse files Browse the repository at this point in the history
  • Loading branch information
lurunze1226 authored Jun 8, 2022
1 parent 53e4c61 commit 8c38e9c
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 78 deletions.
9 changes: 7 additions & 2 deletions src/renderers/Form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface FormSchemaHorizontal {
right?: number;
leftFixed?: boolean | number | 'xs' | 'sm' | 'md' | 'lg';
justify?: boolean; // 两端对齐
labelAlign?: 'left' | 'right' // label对齐方式
labelAlign?: 'left' | 'right'; // label对齐方式
}

/**
Expand Down Expand Up @@ -988,7 +988,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',
Expand Down
55 changes: 31 additions & 24 deletions src/store/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Instance
} from 'mobx-state-tree';
import debounce from 'lodash/debounce';
import find from 'lodash/find';
import {ServiceStore} from './service';
import {FormItemStore, IFormItemStore, SFormItemStore} from './formItem';
import {Api, ApiObject, fetchOptions, Payload} from '../types';
Expand Down Expand Up @@ -326,7 +327,6 @@ export const FormStore = ServiceStore.named('FormStore')
}

if (!json.ok) {

if (json.status === 422 && json.errors) {
setFormItemErrors(json.errors);

Expand Down Expand Up @@ -359,22 +359,23 @@ export const FormStore = ServiceStore.named('FormStore')
);
if (!ret?.dispatcher?.prevented) {
self.msg &&
getEnv(self).notify(
'success',
self.msg,
json.msgTimeout !== undefined
? {
closeButton: true,
timeout: json.msgTimeout
}
: undefined
);
getEnv(self).notify(
'success',
self.msg,
json.msgTimeout !== undefined
? {
closeButton: true,
timeout: json.msgTimeout
}
: undefined
);
}
return json.data;
}
} catch (e) {
self.markSaving(false);
let ret = options && options.onFailed && options.onFailed(e.response || {});
let ret =
options && options.onFailed && options.onFailed(e.response || {});
if (ret?.then) {
ret = yield ret;
}
Expand Down Expand Up @@ -486,7 +487,7 @@ export const FormStore = ServiceStore.named('FormStore')
if (dispatcher?.then) {
dispatcher = yield dispatcher;
}
if (!dispatcher?.prevented){
if (!dispatcher?.prevented) {
msg && env.notify('error', msg);
}
throw new Error(msg);
Expand Down Expand Up @@ -548,20 +549,26 @@ export const FormStore = ServiceStore.named('FormStore')
return self.valid;
});

const validateFields: (fields: Array<string>) => Promise<boolean> = flow(
function* validateFields(fields: Array<string>) {
const items = self.items.concat();
let result: Array<boolean> = [];
for (let i = 0, len = items.length; i < len; i++) {
let item = items[i] as IFormItemStore;
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);
}
);
return result.every(item => item);
});

function clearErrors() {
const items = self.items.concat();
Expand Down
117 changes: 65 additions & 52 deletions src/store/formItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,70 +326,83 @@ 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) {
if (self.validating && !isEffectiveApi(self.validateApi, data)) {
return self.valid;
}

self.validating = true;
clearError();
if (hook) {
yield hook();
}
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;
}

addError(
doValidate(self.tmpValue, data, self.rules, self.messages, self.__)
);
self.validating = true;
clearError();
if (hook) {
yield hook();
}

if (!self.errors.length && isEffectiveApi(self.validateApi, data)) {
if (validateCancel) {
validateCancel();
validateCancel = null;
}
addError(
doValidate(
self.tmpValue,
data,
customRules ? str2rules(customRules) : self.rules,
self.messages,
self.__
)
);

const json: Payload = yield getEnv(self).fetcher(
self.validateApi,
/** 如果配置validateApi,需要将用户最新输入同步到数据域内 */
createObject(data, {[self.name]: self.tmpValue}),
{
cancelExecutor: (executor: Function) =>
(validateCancel = executor)
}
);
if (!self.errors.length && isEffectiveApi(self.validateApi, data)) {
if (validateCancel) {
validateCancel();
validateCancel = null;
}

if (!json.ok && json.status === 422 && json.errors) {
addError(
String(
json.errors || json.msg || `表单项「${self.name}」校验失败`
)
);
const json: Payload = yield getEnv(self).fetcher(
self.validateApi,
/** 如果配置validateApi,需要将用户最新输入同步到数据域内 */
createObject(data, {[self.name]: self.tmpValue}),
{
cancelExecutor: (executor: Function) => (validateCancel = executor)
}
);
validateCancel = null;

if (!json.ok && json.status === 422 && json.errors) {
addError(
String(json.errors || json.msg || `表单项「${self.name}」校验失败`)
);
}
}

self.validated = true;
self.validated = true;

if (self.unique && self.form?.parentStore?.storeType === 'ComboStore') {
const combo = self.form.parentStore as IComboStore;
const group = combo.uniques.get(self.name) as IUniqueGroup;
if (self.unique && self.form?.parentStore?.storeType === 'ComboStore') {
const combo = self.form.parentStore as IComboStore;
const group = combo.uniques.get(self.name) as IUniqueGroup;

if (
group.items.some(
item =>
item !== self &&
self.tmpValue !== undefined &&
item.value === self.tmpValue
)
) {
addError(self.__('Form.unique'));
}
if (
group.items.some(
item =>
item !== self &&
self.tmpValue !== undefined &&
item.value === self.tmpValue
)
) {
addError(self.__('Form.unique'));
}

self.validating = false;
return self.valid;
}
);

self.validating = false;
return self.valid;
});

function setError(msg: string | Array<string>, tag: string = 'builtin') {
clearError();
Expand Down

0 comments on commit 8c38e9c

Please sign in to comment.