Skip to content

Commit

Permalink
fix: form validateFirst not reject #4273
Browse files Browse the repository at this point in the history
  • Loading branch information
tangjinzhou committed Jun 28, 2021
1 parent 4a0fce5 commit 5f8d8a5
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 136 deletions.
40 changes: 33 additions & 7 deletions components/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { VueNode } from '../_util/type';
import { tuple } from '../_util/type';
import type { ColProps } from '../grid/Col';
import type { InternalNamePath, NamePath, ValidateErrorEntity, ValidateOptions } from './interface';
import type {
InternalNamePath,
NamePath,
RuleError,
ValidateErrorEntity,
ValidateOptions,
} from './interface';
import { useInjectSize } from '../_util/hooks/useSize';
import useConfigInject from '../_util/hooks/useConfigInject';
import { useProvideForm } from './context';
Expand Down Expand Up @@ -247,13 +253,33 @@ const Form = defineComponent({
// Wrap promise with field
promiseList.push(
promise
.then(() => ({ name: fieldNamePath, errors: [] }))
.catch((errors: any) =>
Promise.reject({
.then<any, RuleError>(() => ({ name: fieldNamePath, errors: [], warnings: [] }))
.catch((ruleErrors: RuleError[]) => {
const mergedErrors: string[] = [];
const mergedWarnings: string[] = [];

ruleErrors.forEach(({ rule: { warningOnly }, errors }) => {
if (warningOnly) {
mergedWarnings.push(...errors);
} else {
mergedErrors.push(...errors);
}
});

if (mergedErrors.length) {
return Promise.reject({
name: fieldNamePath,
errors: mergedErrors,
warnings: mergedWarnings,
});
}

return {
name: fieldNamePath,
errors,
}),
),
errors: mergedErrors,
warnings: mergedWarnings,
};
}),
);
}
});
Expand Down
12 changes: 7 additions & 5 deletions components/form/FormItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { toArray } from './utils/typeUtil';
import { warning } from '../vc-util/warning';
import find from 'lodash-es/find';
import { tuple } from '../_util/type';
import type { InternalNamePath, RuleObject, ValidateOptions } from './interface';
import type { InternalNamePath, RuleError, RuleObject, ValidateOptions } from './interface';
import useConfigInject from '../_util/hooks/useConfigInject';
import { useInjectForm } from './context';
import FormItemLabel from './FormItemLabel';
Expand All @@ -31,7 +31,7 @@ export interface FieldExpose {
clearValidate: () => void;
namePath: ComputedRef<InternalNamePath>;
rules?: ComputedRef<ValidationRule[]>;
validateRules: (options: ValidateOptions) => Promise<void> | Promise<string[]>;
validateRules: (options: ValidateOptions) => Promise<void> | Promise<RuleError[]>;
}

function getPropByPath(obj: any, namePathList: any, strict?: boolean) {
Expand Down Expand Up @@ -209,10 +209,12 @@ export default defineComponent({

promise
.catch(e => e)
.then((ers = []) => {
.then((results: RuleError[] = []) => {
if (validateState.value === 'validating') {
validateState.value = ers.length ? 'error' : 'success';
errors.value = ers;
const res = results.filter(result => result && result.errors.length);
validateState.value = res.length ? 'error' : 'success';

errors.value = res.map(r => r.errors);
}
});

Expand Down
7 changes: 7 additions & 0 deletions components/form/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ type Validator = (
) => Promise<void> | void;

export interface ValidatorRule {
warningOnly?: boolean;
message?: string | VueNode;
validator: Validator;
}

interface BaseRule {
warningOnly?: boolean;
enum?: StoreValue[];
len?: number;
max?: number;
Expand Down Expand Up @@ -92,6 +94,11 @@ export interface FieldError {
errors: string[];
}

export interface RuleError {
errors: string[];
rule: RuleObject;
}

export interface ValidateOptions {
triggerName?: string;
validateMessages?: ValidateMessages;
Expand Down
3 changes: 2 additions & 1 deletion components/form/utils/asyncUtil.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { FieldError } from '../interface';

export function allPromiseFinish(promiseList: Promise<FieldError>[]): Promise<FieldError[]> {
let hasError = false;
let count = promiseList.length;
const results = [];
const results: FieldError[] = [];

if (!promiseList.length) {
return Promise.resolve([]);
Expand Down
Loading

0 comments on commit 5f8d8a5

Please sign in to comment.