You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
5.6 KiB
197 lines
5.6 KiB
import baseComponent from '../helpers/baseComponent'
|
|
import createFieldsStore from '../helpers/createFieldsStore'
|
|
|
|
const DEFAULT_TRIGGER = 'onChange'
|
|
|
|
function noop() {}
|
|
|
|
function getValueFromEvent(e) {
|
|
// To support custom element
|
|
if (!e || !e.detail) {
|
|
if ('value' in e) {
|
|
return e.value
|
|
}
|
|
return e
|
|
}
|
|
return e.detail.value
|
|
}
|
|
|
|
const children = [
|
|
'picker',
|
|
'date-picker',
|
|
'popup-select',
|
|
'radio-group',
|
|
'checkbox-group',
|
|
'switch',
|
|
'input',
|
|
'input-number',
|
|
'rater',
|
|
'slider',
|
|
'textarea',
|
|
]
|
|
|
|
const relations = children.map((name) => `../${name}/index`).reduce((acc, name) => {
|
|
return {
|
|
...acc,
|
|
[name]: {
|
|
type: 'descendant',
|
|
observer: function() {
|
|
this.debounce(this.changeValue)
|
|
},
|
|
},
|
|
}
|
|
}, {})
|
|
|
|
baseComponent({
|
|
useField: true,
|
|
relations: {
|
|
'../form/index': {
|
|
type: 'ancestor',
|
|
},
|
|
...relations,
|
|
},
|
|
properties: {
|
|
initialValue: {
|
|
type: null,
|
|
value: null,
|
|
observer: 'changeValue',
|
|
},
|
|
valuePropName: {
|
|
type: String,
|
|
value: 'inputValue',
|
|
},
|
|
trigger: {
|
|
type: String,
|
|
value: DEFAULT_TRIGGER,
|
|
},
|
|
},
|
|
methods: {
|
|
/**
|
|
* 获取子节点
|
|
*/
|
|
getNodes(relations = []) {
|
|
return relations.map((name) => this.getRelationNodes(name)[0]).filter((v) => !!v)
|
|
},
|
|
/**
|
|
* 更新 value 值,同步到子元素
|
|
*/
|
|
changeValue(value = this.data.value) {
|
|
const relations = this.getRelationsName(['descendant'])
|
|
const elements = this.getNodes(relations)
|
|
|
|
this.fieldsStore = this.fieldsStore || createFieldsStore()
|
|
this.setValue(value)
|
|
|
|
if (elements.length > 0) {
|
|
elements.forEach((inputElem) => {
|
|
inputElem.hasFieldDecorator = true
|
|
this.setValue(value, inputElem, this.data.valuePropName, () => {
|
|
this.forceUpdate(this.data.name, this.data, inputElem)
|
|
})
|
|
})
|
|
}
|
|
},
|
|
/**
|
|
* 设置 value 值
|
|
*/
|
|
setValue(value, elem = this, valuePropName = 'value', callback = noop) {
|
|
if (elem.data[valuePropName] !== value) {
|
|
elem.setData({ [valuePropName]: value }, callback)
|
|
} else {
|
|
callback()
|
|
}
|
|
},
|
|
/**
|
|
* 强制更新元素
|
|
*/
|
|
forceUpdate(name, fieldOption, inputElem) {
|
|
const { valuePropName } = fieldOption
|
|
const inputProps = this.getFieldDecorator(name, fieldOption, inputElem)
|
|
const inputValue = inputProps[valuePropName]
|
|
|
|
delete inputProps[valuePropName]
|
|
|
|
inputElem.setData(inputProps)
|
|
this.setValue(inputValue, inputElem, valuePropName)
|
|
},
|
|
/**
|
|
* 同步子元素
|
|
*/
|
|
onCollectCommon(name, action, args) {
|
|
const field = this.fieldsStore.getField(name)
|
|
const { inputElem, oriInputProps } = field
|
|
const { oriInputEvents } = oriInputProps
|
|
|
|
// trigger inputElem func
|
|
if (oriInputEvents && oriInputEvents[action]) {
|
|
oriInputEvents[action](...args)
|
|
}
|
|
|
|
const value = getValueFromEvent(...args)
|
|
const oldValue = this.fieldsStore.getFieldValue(name)
|
|
const parent = this.getRelationNodes('../form/index')[0]
|
|
|
|
// set field value
|
|
if (value !== oldValue) {
|
|
this.setValue(value)
|
|
this.setValue(value, inputElem, field.valuePropName)
|
|
|
|
// trigger onChange
|
|
if (parent) {
|
|
const changedValues = { [name]: value }
|
|
const allValues = this.fieldsStore.getFieldsValue()
|
|
parent.onChange(changedValues, { ...allValues, ...changedValues })
|
|
}
|
|
}
|
|
|
|
return {
|
|
name,
|
|
field: {
|
|
...field,
|
|
value,
|
|
},
|
|
}
|
|
},
|
|
/**
|
|
* 同步子元素
|
|
*/
|
|
onCollect(name_, action, ...args) {
|
|
const { name, field } = this.onCollectCommon(name_, action, args)
|
|
|
|
this.fieldsStore.setFields({ [name]: field })
|
|
},
|
|
/**
|
|
* 字段装饰器
|
|
*/
|
|
getFieldDecorator(name, fieldOption, inputElem) {
|
|
const field = this.fieldsStore.getField(name)
|
|
const { data: oriInputProps } = inputElem
|
|
const { trigger = DEFAULT_TRIGGER } = fieldOption
|
|
|
|
const meta = {
|
|
...field,
|
|
...fieldOption,
|
|
name,
|
|
oriInputProps,
|
|
inputElem,
|
|
}
|
|
|
|
this.fieldsStore.setFields({ [name]: meta })
|
|
|
|
const inputProps = {
|
|
...this.fieldsStore.getFieldValuePropValue(fieldOption),
|
|
}
|
|
|
|
// set input events, rewrite `trigger` func
|
|
if (trigger && !oriInputProps.oriInputEvents) {
|
|
inputProps.oriInputEvents = { ...oriInputProps.inputEvents }
|
|
inputProps.inputEvents = {
|
|
...oriInputProps.inputEvents,
|
|
[trigger]: (...args) => this.onCollect(name, trigger, ...args),
|
|
}
|
|
}
|
|
|
|
return inputProps
|
|
},
|
|
},
|
|
})
|
|
|