Skip to content

Commit

Permalink
fix(core): Fix the problem that the initialValues cannot be synchroni…
Browse files Browse the repository at this point in the history
…zed to values repeatedly
  • Loading branch information
janryWang committed Jan 27, 2021
1 parent aa52a42 commit 09e0f70
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 111 deletions.
6 changes: 3 additions & 3 deletions packages/core/src/__tests__/effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ test('onFormValuesChange/onFormInitialValuesChange', () => {
aa: '321',
bb: '123',
})
expect(form.values.aa).toEqual('123')
expect(form.values.aa).toEqual('321')
expect(form.values.bb).toEqual('123')
expect(initialValuesChange).toBeCalled()
})
Expand Down Expand Up @@ -360,11 +360,11 @@ test('onFieldInitialValueChange/onFieldValueChange/onFieldInputValueChange', ()
expect(fieldInitialValueChange).toBeCalledTimes(0)
expect(fieldInputValueChange).toBeCalledTimes(0)
field.setInitialValue('xxx')
expect(fieldValueChange).toBeCalledTimes(1)
expect(fieldValueChange).toBeCalledTimes(2)
expect(fieldInitialValueChange).toBeCalledTimes(1)
expect(fieldInputValueChange).toBeCalledTimes(0)
field.onInput('321')
expect(fieldValueChange).toBeCalledTimes(2)
expect(fieldValueChange).toBeCalledTimes(3)
expect(fieldInitialValueChange).toBeCalledTimes(1)
expect(fieldInputValueChange).toBeCalledTimes(1)
expect(notTrigger).toBeCalledTimes(0)
Expand Down
47 changes: 22 additions & 25 deletions packages/core/src/models/ArrayField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,95 +26,92 @@ export class ArrayField<
)
}

push = (...items: any[]) => {
push = async (...items: any[]) => {
if (!isArr(this.value)) return
return runInAction(() => {
this.value.push(...items)
this.validate('onInput')
return this.onInput(this.value)
})
}

pop = () => {
pop = async () => {
if (!isArr(this.value)) return
return runInAction(() => {
const index = this.value.length - 1
const poped = this.value.pop()
this.value.pop()
spliceArrayState(this, {
startIndex: index,
deleteCount: 1,
})
this.validate('onInput')
return poped
return this.onInput(this.value)
})
}

insert = (index: number, ...items: any[]) => {
insert = async (index: number, ...items: any[]) => {
if (!isArr(this.value)) return
runInAction(() => {
return runInAction(() => {
this.value.splice(index, 0, ...items)
spliceArrayState(this, {
startIndex: index,
insertCount: items.length,
})
this.validate('onInput')
return this.onInput(this.value)
})
}

remove = (index: number) => {
remove = async (index: number) => {
if (!isArr(this.value)) return
runInAction(() => {
return runInAction(() => {
this.value.splice(index, 1)
spliceArrayState(this, {
startIndex: index,
deleteCount: 1,
})
this.validate('onInput')
return this.onInput(this.value)
})
}

shift = () => {
shift = async () => {
if (!isArr(this.value)) return
return runInAction(() => {
const shifted = this.value.shift()
this.validate('onInput')
return shifted
this.value.shift()
return this.onInput(this.value)
})
}

unshift = (...items: any[]) => {
unshift = async (...items: any[]) => {
if (!isArr(this.value)) return
return runInAction(() => {
const unshifted = this.value.unshift(...items)
this.value.unshift(...items)
spliceArrayState(this, {
startIndex: 0,
insertCount: items.length,
})
this.validate('onInput')
return unshifted
return this.onInput(this.value)
})
}

move = (fromIndex: number, toIndex: number) => {
move = async (fromIndex: number, toIndex: number) => {
if (!isArr(this.value)) return
if (fromIndex === toIndex) return
runInAction(() => {
return runInAction(() => {
const fromItem = this.value[fromIndex]
this.value.splice(fromIndex, 1)
this.value.splice(toIndex, 0, fromItem)
exchangeArrayState(this, {
fromIndex,
toIndex,
})
this.validate('onInput')
return this.onInput(this.value)
})
}

moveUp = (index: number) => {
moveUp = async (index: number) => {
if (!isArr(this.value)) return
return this.move(index, index - 1 < 0 ? this.value.length - 1 : index - 1)
}

moveDown = (index: number) => {
moveDown = async (index: number) => {
if (!isArr(this.value)) return
return this.move(index, index + 1 >= this.value.length ? 0 : index + 1)
}
Expand Down
17 changes: 15 additions & 2 deletions packages/core/src/models/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,18 @@ export class Field<

onInit = () => {
this.initialized = true
if (isEmpty(this.initialValue)) {
if (isValid(this.props.initialValue)) {
this.initialValue = this.props.initialValue
}
}
if (isEmpty(this.value)) {
if (isValid(this.props.value)) {
this.value = this.props.value
} else if (!isEmpty(this.initialValue)) {
this.value = this.initialValue
}
}
this.form.notify(LifeCycleTypes.ON_FIELD_INIT, this)
publishUpdate(this)
}
Expand Down Expand Up @@ -706,9 +718,10 @@ export class Field<
this.feedbacks = []
this.inputValue = undefined
this.inputValues = []
this.value = undefined
if (options?.forceClear) {
this.initialValue = undefined
this.value = undefined
} else {
this.value = this.initialValue
}
this.form.notify(LifeCycleTypes.ON_FIELD_RESET, this)

Expand Down
88 changes: 41 additions & 47 deletions packages/core/src/models/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
uid,
globalThisPolyfill,
defaults,
isEmpty,
clone,
} from '@formily/shared'
import { Heart } from './Heart'
Expand Down Expand Up @@ -48,6 +47,7 @@ import {
createModelStateSetter,
createFieldStateSetter,
createFieldStateGetter,
applyValuesPatch,
} from '../shared'
import { ArrayField } from './ArrayField'
import { ObjectField } from './ObjectField'
Expand All @@ -66,8 +66,8 @@ export class Form<ValueType = any> {
modified: boolean
pattern: FormPatternTypes
display: FormDisplayTypes
originValues: ValueType
originInitialValues: ValueType
values: ValueType
initialValues: ValueType
mounted: boolean
unmounted: boolean
props: IFormProps
Expand All @@ -80,6 +80,7 @@ export class Form<ValueType = any> {

constructor(props: IFormProps) {
this.initialize(props)
this.makeInitialValues()
this.makeObservable()
this.makeReactive()
this.onInit()
Expand All @@ -102,19 +103,23 @@ export class Form<ValueType = any> {
this.readPretty = this.props.readPretty
this.visible = this.props.visible
this.hidden = this.props.hidden
this.originValues = isObservable(this.props.values)
? this.props.values
: clone(this.props.values) || ({} as any)
this.originInitialValues = isObservable(this.props.values)
? this.props.initialValues
: clone(this.props.initialValues) || ({} as any)
this.graph = new Graph(this)
this.heart = new Heart({
lifecycles: this.lifecycles,
context: this,
})
}

protected makeInitialValues() {
this.values = isObservable(this.props.values)
? this.props.values
: clone(this.props.values) || ({} as any)
this.initialValues = isObservable(this.props.initialValues)
? this.props.initialValues
: clone(this.props.initialValues) || ({} as any)
applyValuesPatch(this, [], this.initialValues)
}

protected makeObservable() {
makeObservable(this, {
fields: observable.shallow,
Expand All @@ -126,8 +131,8 @@ export class Form<ValueType = any> {
display: observable.ref,
mounted: observable.ref,
unmounted: observable.ref,
originValues: observable,
originInitialValues: observable,
values: observable,
initialValues: observable,
setValues: action,
setValuesIn: action,
setInitialValues: action,
Expand All @@ -149,12 +154,21 @@ export class Form<ValueType = any> {

protected makeReactive() {
this.disposers.push(
observer(this.originInitialValues, () => {
this.notify(LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE)
}),
observer(this.originValues, () => {
this.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)
})
observer(
() => this.initialValues,
(change, path) => {
if (change.type === 'add' || change.type === 'update') {
applyValuesPatch(this, path, change.newValue)
}
this.notify(LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE)
}
),
observer(
() => this.values,
() => {
this.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)
}
)
)
}

Expand Down Expand Up @@ -266,24 +280,6 @@ export class Form<ValueType = any> {
}
}

set values(values: ValueType) {
this.originValues = values
this.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)
}

get values() {
return defaults(this.originInitialValues, this.originValues)
}

set initialValues(initialValues: ValueType) {
this.originInitialValues = initialValues
this.notify(LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE)
}

get initialValues() {
return this.originInitialValues
}

/** 创建字段 **/

createField = <
Expand Down Expand Up @@ -362,7 +358,7 @@ export class Form<ValueType = any> {

setValues = (values: any, strategy: 'overwrite' | 'merge' = 'merge') => {
if (strategy === 'merge') {
this.values = defaults(this.originValues, values)
this.values = defaults(this.values, values)
} else {
this.values = values
}
Expand All @@ -373,44 +369,42 @@ export class Form<ValueType = any> {
strategy: 'overwrite' | 'merge' = 'merge'
) => {
if (strategy === 'merge') {
this.initialValues = defaults(this.originInitialValues, initialValues)
this.initialValues = defaults(this.initialValues, initialValues)
} else {
this.initialValues = initialValues
}
}

setValuesIn = (pattern: FormPathPattern, value: any) => {
FormPath.setIn(this.originValues, pattern, value)
FormPath.setIn(this.values, pattern, value)
}

deleteValuesIn = (pattern: FormPathPattern) => {
FormPath.deleteIn(this.originValues, pattern)
FormPath.deleteIn(this.values, pattern)
}

existValuesIn = (pattern: FormPathPattern) => {
return FormPath.existIn(this.originValues, pattern)
return FormPath.existIn(this.values, pattern)
}

getValuesIn = (pattern: FormPathPattern) => {
const value = FormPath.getIn(this.originValues, pattern)
const initialValue = FormPath.getIn(this.originInitialValues, pattern)
return isEmpty(value) && isValid(initialValue) ? initialValue : value
return FormPath.getIn(this.values, pattern)
}

setInitialValuesIn = (pattern: FormPathPattern, initialValue: any) => {
FormPath.setIn(this.originInitialValues, pattern, initialValue)
FormPath.setIn(this.initialValues, pattern, initialValue)
}

deleteIntialValuesIn = (pattern: FormPathPattern) => {
FormPath.deleteIn(this.originInitialValues, pattern)
FormPath.deleteIn(this.initialValues, pattern)
}

existInitialValuesIn = (pattern: FormPathPattern) => {
return FormPath.existIn(this.originInitialValues, pattern)
return FormPath.existIn(this.initialValues, pattern)
}

getInitialValuesIn = (pattern: FormPathPattern) => {
return FormPath.getIn(this.originInitialValues, pattern)
return FormPath.getIn(this.initialValues, pattern)
}

setSubmitting = (submitting: boolean) => {
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/models/ObjectField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ export class ObjectField<
)
}

addProperty = (key: FormPathPattern, value: any) => {
addProperty = async (key: FormPathPattern, value: any) => {
this.form.setValuesIn(this.path.concat(key), value)
return this.onInput(this.value)
}

removeProperty = (key: FormPathPattern) => {
removeProperty = async (key: FormPathPattern) => {
this.form.deleteValuesIn(this.path.concat(key))
return this.onInput(this.value)
}

existProperty = (key: FormPathPattern) => {
Expand Down
Loading

0 comments on commit 09e0f70

Please sign in to comment.