Skip to content

Commit

Permalink
feat(core): support value change trigger validate
Browse files Browse the repository at this point in the history
  • Loading branch information
janryWang committed May 19, 2021
1 parent fb9b281 commit 0473017
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 26 deletions.
67 changes: 45 additions & 22 deletions packages/core/src/models/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ import {
} from '../shared'
import { Query } from './Query'

const RESPONSE_REQUEST_DURATION = 100

export class Field<
Decorator extends JSXComponent = any,
Component extends JSXComponent = any,
Expand Down Expand Up @@ -226,8 +228,11 @@ export class Field<
this.disposers.push(
reaction(
() => this.value,
() => {
(value) => {
this.form.notify(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, this)
if (isValid(value) && this.modified && !this.caches.inputing) {
this.validate()
}
}
),
reaction(
Expand Down Expand Up @@ -581,28 +586,28 @@ export class Field<
}

setLoading = (loading?: boolean) => {
clearTimeout(this.requests.loader)
clearTimeout(this.requests.loading)
if (loading) {
this.requests.loader = setTimeout(() => {
this.requests.loading = setTimeout(() => {
batch(() => {
this.loading = loading
this.form.notify(LifeCycleTypes.ON_FIELD_LOADING, this)
})
}, 100)
}, RESPONSE_REQUEST_DURATION)
} else if (this.loading !== loading) {
this.loading = loading
}
}

setValidating = (validating?: boolean) => {
clearTimeout(this.requests.validate)
clearTimeout(this.requests.validating)
if (validating) {
this.requests.validate = setTimeout(() => {
this.requests.validating = setTimeout(() => {
batch(() => {
this.validating = validating
this.form.notify(LifeCycleTypes.ON_FIELD_VALIDATING, this)
})
}, 100)
}, RESPONSE_REQUEST_DURATION)
} else if (this.validating !== validating) {
this.validating = validating
}
Expand Down Expand Up @@ -685,6 +690,7 @@ export class Field<
}
const values = getValuesFromEvent(args)
const value = values[0]
this.caches.inputing = true
this.inputValue = value
this.inputValues = values
this.value = value
Expand All @@ -693,6 +699,7 @@ export class Field<
this.form.notify(LifeCycleTypes.ON_FIELD_INPUT_VALUE_CHANGE, this)
this.form.notify(LifeCycleTypes.ON_FORM_INPUT_CHANGE, this.form)
await this.validate('onInput')
this.caches.inputing = false
}

onFocus = async (...args: any[]) => {
Expand Down Expand Up @@ -726,25 +733,41 @@ export class Field<
}
this.form.notify(LifeCycleTypes.ON_FIELD_VALIDATE_END, this)
}
start()
if (!triggerType) {
const allTriggerTypes = parseValidatorDescriptions(this.validator).map(
(desc) => desc.triggerType
)
const results = {}
for (let i = 0; i < allTriggerTypes.length; i++) {
const payload = await validateToFeedbacks(this, allTriggerTypes[i])
each(payload, (result, key) => {
results[key] = results[key] || []
results[key] = results[key].concat(result)
})
const runner = async () => {
if (!triggerType) {
const allTriggerTypes = parseValidatorDescriptions(this.validator).map(
(desc) => desc.triggerType
)
const results = {}
for (let i = 0; i < allTriggerTypes.length; i++) {
const payload = await validateToFeedbacks(this, allTriggerTypes[i])
each(payload, (result, key) => {
results[key] = results[key] || []
results[key] = results[key].concat(result)
})
}
end()
return results
}
const results = await validateToFeedbacks(this, triggerType)
end()

return results
}
const results = await validateToFeedbacks(this, triggerType)
end()
return results

start()

return new Promise((resolve) => {
cancelAnimationFrame(this.requests.validate)

this.requests.validate = requestAnimationFrame(() => {
const results = runner()
this.requests.validateResolvers.forEach((resolve) => resolve(results))
})

this.requests.validateResolvers = this.requests.validateResolvers || []
this.requests.validateResolvers.push(resolve)
})
}

reset = async (options?: IFieldResetOptions) => {
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/models/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ import { Graph } from './Graph'

const DEV_TOOLS_HOOK = '__FORMILY_DEV_TOOLS_HOOK__'

const RESPONSE_REQUEST_DURATION = 100

export class Form<ValueType extends object = any> {
displayName = 'Form'
id: string
Expand Down Expand Up @@ -462,7 +464,7 @@ export class Form<ValueType extends object = any> {
this.submitting = submitting
this.notify(LifeCycleTypes.ON_FORM_SUBMITTING)
})
}, 100)
}, RESPONSE_REQUEST_DURATION)
this.notify(LifeCycleTypes.ON_FORM_SUBMIT_START)
} else {
if (this.submitting !== submitting) {
Expand All @@ -480,7 +482,7 @@ export class Form<ValueType extends object = any> {
this.validating = validating
this.notify(LifeCycleTypes.ON_FORM_VALIDATING)
})
}, 100)
}, RESPONSE_REQUEST_DURATION)
this.notify(LifeCycleTypes.ON_FORM_VALIDATE_START)
} else {
if (this.validating !== validating) {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,18 @@ export interface IVoidFieldFactoryProps<
}

export interface IFieldRequests {
validate?: NodeJS.Timeout
loader?: NodeJS.Timeout
validate?: number
validateResolvers?: Array<(value: any) => void>
validating?: NodeJS.Timeout
loading?: NodeJS.Timeout
batch?: () => void
}

export interface IFieldCaches {
value?: any
initialValue?: any
feedbacks?: IFieldFeedback[]
inputing?: boolean
}

export type FieldDisplayTypes = 'none' | 'hidden' | 'visible' | ({} & string)
Expand Down

0 comments on commit 0473017

Please sign in to comment.