Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): fix field default sync exception #970

Merged
merged 3 commits into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 0 additions & 53 deletions docs/zh-cn/schema-develop/form-value.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,56 +167,3 @@ ReactDOM.render(<App />, document.getElementById('root'))
- 先点击刷新,后点击重置,点击刷新的时候,initialValues 受表单重渲染而重新更新,aa 字段的初始值更新了,但是因为 aa 当前是有值状态,所以不会被默认值更新所影响
- 先点击刷新,后点击重置,点击重置按钮的时候,默认是会将值变为初始值,因为初始值变了,所以 aa 字段的值也变了,如果不希望出现这种行为,可以给重置按钮配置强制清空
- 交替点击清空和刷新按钮,可以重复赋值,是因为初始值一直在变,清空使得字段又恢复到无默认值状态,所以是可以持续赋值的,看着就像前面 value 的效果一样

# InitialValues 覆盖 default

```jsx
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import {
SchemaForm,
SchemaMarkupField as Field,
FormButtonGroup,
Reset
} from '@formily/antd'
import { Input } from '@formily/antd-components'
import { Button } from 'antd'
import Printer from '@formily/printer'
import 'antd/dist/antd.css'

const App = () => {
const [value, setValue] = useState({
aa: 'first render value'
})
return (
<Printer>
<SchemaForm
initialValues={value}
components={{
Input
}}
>
<Field type="string" name="aa" x-component="Input" default="123" />
<Field type="string" name="bb" x-component="Input" default="321" />
<FormButtonGroup>
<Button
onClick={() => {
setValue({
aa: Math.random() * 1000 + '',
bb: Math.random() * 1000 + ''
})
}}
>
刷新
</Button>
<Reset>重置</Reset>
<Reset forceClear>清空</Reset>
</FormButtonGroup>
</SchemaForm>
</Printer>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
```

如果字段从未被修改过值,initialValues 会覆盖 default 属性的值,如果已经修改过值,那么无法覆盖
15 changes: 11 additions & 4 deletions packages/core/src/externals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const createFormExternals = (
heart,
graph,
validator,
upload,
hostUpdate,
afterUnmount,
nextTick,
Expand Down Expand Up @@ -225,7 +226,7 @@ export const createFormExternals = (
if (dirtys.initialized) {
heart.publish(LifeCycleTypes.ON_FIELD_INIT, field)
}
if (dirtys.value) {
if (dirtys.value || dirtys.values) {
const isArrayList = /array/gi.test(published.dataType)
if (isArrayList) {
const prevTags = parseArrayTags(field.prevState.value)
Expand Down Expand Up @@ -393,14 +394,20 @@ export const createFormExternals = (
return form.getState(state => state.editable)
},
setValue(name, value) {
setFormValuesIn(name, value)
upload(() => {
setFormValuesIn(name, value)
})
},
setInitialValue(name, value) {
setFormInitialValuesIn(name, value)
upload(() => {
setFormInitialValuesIn(name, value)
})
},
removeValue(name) {
if (!graph.get(nodePath)) return
deleteFormValuesIn(name)
upload(() => {
deleteFormValuesIn(name)
})
},
getInitialValue(name) {
return getFormInitialValuesIn(name)
Expand Down
18 changes: 16 additions & 2 deletions packages/core/src/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
isValid,
isEqual,
clone,
isFn
isFn,
defaults
} from '@formily/shared'
import {
LifeCycleTypes,
Expand All @@ -29,6 +30,11 @@ export const createFormInternals = (options: IFormCreatorOptions = {}) => {
notifyFormValuesChange()
}
if (dirtys.initialValues) {
if (!env.uploading) {
form.setState(state => {
state.values = defaults(published.initialValues, published.values)
})
}
notifyFormInitialValuesChange()
}
if (dirtys.unmounted && published.unmounted) {
Expand Down Expand Up @@ -366,10 +372,16 @@ export const createFormInternals = (options: IFormCreatorOptions = {}) => {
return true
}

function upload(callback: () => void) {
env.uploading = true
callback()
env.uploading = false
}

const graph = new FormGraph({
matchStrategy
})
const form = new Form(options)
const form = new Form()
const validator = new FormValidator({
...options,
matchStrategy
Expand All @@ -392,6 +404,7 @@ export const createFormInternals = (options: IFormCreatorOptions = {}) => {
hostRendering: false,
publishing: {},
taskQueue: [],
uploading: false,
taskIndexes: {},
realRemoveTags: [],
lastShownStates: {},
Expand All @@ -410,6 +423,7 @@ export const createFormInternals = (options: IFormCreatorOptions = {}) => {
validator,
heart,
env,
upload,
nextTick,
afterUnmount,
getDataPath,
Expand Down
12 changes: 2 additions & 10 deletions packages/core/src/models/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ export const Field = createModel<IFieldState, IFieldStateProps>(
return true
}
}

return !isEqual(currentValue, nextValue)
}

Expand Down Expand Up @@ -154,18 +153,11 @@ export const Field = createModel<IFieldState, IFieldStateProps>(
let initialValue = this.getInitialValueFromProps()
let formEditable = this.getEditableFromProps()
if (this.isArrayList()) {
value = this.tagArrayList(toArr(value))
initialValue = this.tagArrayList(toArr(initialValue))
value = toArr(value)
initialValue = toArr(initialValue)
}

const valueChanged = !isEqual(this.state.value, value)

if (!this.state.inputed) {
if (isEqual(value, this.state.initialValue)) {
value = initialValue
}
}

const state = {
...this.state,
initialValue,
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/models/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
IFormStateProps,
FormStateDirtyMap
} from '../types'
import { toArr, defaults } from '@formily/shared'
import { toArr } from '@formily/shared'
import { Draft } from 'immer'

const normalizeMessages = (messages: any) => toArr(messages).filter(v => !!v)
Expand All @@ -29,6 +29,12 @@ export const Form = createModel<IFormState, IFormStateProps>(
unmounted: false
}

props: IFormStateProps

constructor(props: IFormStateProps) {
this.props = props
}

produce(draft: Draft<IFormState>, dirtys: FormStateDirtyMap) {
if (dirtys.errors) {
draft.errors = normalizeMessages(draft.errors)
Expand All @@ -48,9 +54,6 @@ export const Form = createModel<IFormState, IFormStateProps>(
draft.modified = true
}
}
if (dirtys.initialValues) {
draft.values = defaults(draft.initialValues, draft.values)
}
if (dirtys.validating) {
if (draft.validating === true) {
draft.loading = true
Expand Down
7 changes: 3 additions & 4 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,14 @@ export interface IFormState<FormProps = any> {

export type FormStateDirtyMap = StateDirtyMap<IFormState>

export interface IFormStateProps {
export type IFormStateProps = {}

export interface IFormCreatorOptions {
initialValues?: {}
values?: {}
lifecycles?: FormLifeCycle[]
editable?: boolean | ((name: string) => boolean)
validateFirst?: boolean
}

export interface IFormCreatorOptions extends IFormStateProps {
onChange?: (values: IFormState['values']) => void
onSubmit?: (values: IFormState['values']) => any | Promise<any>
onReset?: () => void
Expand Down