mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
parent
5a49c43a3d
commit
41d3b12ed7
@ -1558,6 +1558,16 @@ order: 2
|
||||
}
|
||||
```
|
||||
|
||||
**初始不填充**
|
||||
|
||||
从 3.1.0 版本开始,表单初始化时,选项有值时也会执行「自动填充」逻辑,从版本 6.1.0 版本开始 可以通过 `initAutoFill` 配置成 `false` 来关闭。
|
||||
|
||||
`initAutoFill` 有三种值分别如下,默认为 `fillIfNotSet`。
|
||||
|
||||
- `fillIfNotSet` 如果目标值不存在则填充,如果目标值存在则不填充。
|
||||
- `true` 总是填充,如果目标值存在则覆盖。
|
||||
- `false` 总是不填充,如果目标值存在则不填充。
|
||||
|
||||
## 控制选项高度
|
||||
|
||||
> 1.10.0 及以上版本
|
||||
|
@ -54,7 +54,7 @@ import isPlainObject from 'lodash/isPlainObject';
|
||||
import {normalizeOptions} from '../utils/normalizeOptions';
|
||||
import {optionValueCompare} from '../utils/optionValueCompare';
|
||||
import type {Option} from '../types';
|
||||
import {resolveEventData} from '../utils';
|
||||
import {deleteVariable, resolveEventData} from '../utils';
|
||||
|
||||
export {Option};
|
||||
|
||||
@ -203,6 +203,12 @@ export interface FormOptionsControl extends FormBaseControl {
|
||||
autoFill?: {
|
||||
[propName: string]: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* @default fillIfNotSet
|
||||
* 初始化时是否把其他字段同步到表单内部。
|
||||
*/
|
||||
initAutoFill?: boolean | 'fillIfNotSet';
|
||||
}
|
||||
|
||||
export interface OptionsBasicConfig extends FormItemBasicConfig {
|
||||
@ -303,6 +309,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
placeholder: 'Select.placeholder',
|
||||
resetValue: '',
|
||||
deleteConfirmText: 'deleteConfirm',
|
||||
initAutoFill: 'fillIfNotSet',
|
||||
...Control.defaultProps
|
||||
};
|
||||
static propsList: any = (Control as any).propsList
|
||||
@ -314,6 +321,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
|
||||
input: any;
|
||||
mounted = false;
|
||||
initedFilled = false;
|
||||
|
||||
constructor(props: OptionsProps) {
|
||||
super(props);
|
||||
@ -356,16 +364,27 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
JSON.stringify(formItem.getSelectedOptions(formItem.tmpValue)),
|
||||
() =>
|
||||
this.mounted &&
|
||||
this.initedFilled &&
|
||||
this.syncAutoFill(formItem.getSelectedOptions(formItem.tmpValue))
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
options &&
|
||||
formItem.tmpValue &&
|
||||
formItem.getSelectedOptions(formItem.tmpValue).length
|
||||
) {
|
||||
this.syncAutoFill(formItem.getSelectedOptions(formItem.tmpValue));
|
||||
if (formInited || !addHook) {
|
||||
this.initedFilled = true;
|
||||
this.props.initAutoFill !== false &&
|
||||
this.syncAutoFill(
|
||||
formItem.getSelectedOptions(formItem.tmpValue),
|
||||
this.props.initAutoFill === 'fillIfNotSet'
|
||||
);
|
||||
} else if (addHook) {
|
||||
addHook(() => {
|
||||
this.initedFilled = true;
|
||||
this.props.initAutoFill !== false &&
|
||||
this.syncAutoFill(
|
||||
formItem.getSelectedOptions(formItem.tmpValue),
|
||||
this.props.initAutoFill === 'fillIfNotSet'
|
||||
);
|
||||
}, 'init');
|
||||
}
|
||||
|
||||
// 默认全选。这里会和默认值\回填值逻辑冲突,所以如果有配置source则不执行默认全选
|
||||
@ -530,7 +549,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
syncAutoFill(selectedOptions: Array<any>) {
|
||||
syncAutoFill(selectedOptions: Array<any>, skipIfExits = false) {
|
||||
const {autoFill, multiple, onBulkChange, data} = this.props;
|
||||
const formItem = this.props.formItem as IFormItemStore;
|
||||
// 参照录入|自动填充
|
||||
@ -579,13 +598,21 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||
|
||||
Object.keys(autoFill).forEach(key => {
|
||||
const keys = keyToPath(key);
|
||||
let value = getVariable(toSync, key);
|
||||
|
||||
if (skipIfExits) {
|
||||
const originValue = getVariable(data, key);
|
||||
if (typeof originValue !== 'undefined') {
|
||||
value = originValue;
|
||||
}
|
||||
}
|
||||
|
||||
setVariable(result, key, value);
|
||||
|
||||
// 如果左边的 key 是一个路径
|
||||
// 这里不希望直接把原始对象都给覆盖没了
|
||||
// 而是保留原始的对象,只修改指定的属性
|
||||
if (keys.length > 1 && isPlainObject(tmpData[keys[0]])) {
|
||||
const value = getVariable(toSync, key);
|
||||
|
||||
// 存在情况:依次更新同一子路径的多个key,eg: a.b.c1 和 a.b.c2,所以需要同步更新data
|
||||
setVariable(tmpData, key, value);
|
||||
result[keys[0]] = tmpData[keys[0]];
|
||||
|
@ -399,3 +399,206 @@ test('Form:options:autoFill:validation', async () => {
|
||||
expect(screen.queryByText(validationMsg1)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(validationMsg2)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('6. AutoFill initAutoFill fillIfNotSet', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
const {debug, container, getByText, findByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
title: 'The form',
|
||||
controls: [
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'aId',
|
||||
value: 123
|
||||
},
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'bId'
|
||||
},
|
||||
{
|
||||
type: 'radios',
|
||||
name: 'a',
|
||||
autoFill: {
|
||||
aValue: '${value}',
|
||||
aLabel: '${label}',
|
||||
aId: '${id}',
|
||||
bId: '${id}'
|
||||
},
|
||||
value: 'a',
|
||||
options: [
|
||||
{
|
||||
label: 'OptionA',
|
||||
value: 'a',
|
||||
id: 233
|
||||
},
|
||||
{
|
||||
label: 'OptionB',
|
||||
value: 'b'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
submitText: 'Submit'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
onSubmit: onSubmit
|
||||
},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
|
||||
await wait(200);
|
||||
fireEvent.click(getByText(/Submit/));
|
||||
await wait(200);
|
||||
|
||||
expect(onSubmit).toBeCalledTimes(1);
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchObject({
|
||||
aId: 123,
|
||||
a: 'a',
|
||||
aValue: 'a',
|
||||
aLabel: 'OptionA',
|
||||
bId: 233
|
||||
});
|
||||
});
|
||||
|
||||
test('7. AutoFill initAutoFill false', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
const {debug, container, getByText, findByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
title: 'The form',
|
||||
controls: [
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'aId',
|
||||
value: 123
|
||||
},
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'bId'
|
||||
},
|
||||
{
|
||||
type: 'radios',
|
||||
name: 'a',
|
||||
autoFill: {
|
||||
aValue: '${value}',
|
||||
aLabel: '${label}',
|
||||
aId: '${id}',
|
||||
bId: '${id}'
|
||||
},
|
||||
initAutoFill: false,
|
||||
value: 'a',
|
||||
options: [
|
||||
{
|
||||
label: 'OptionA',
|
||||
value: 'a',
|
||||
id: 233
|
||||
},
|
||||
{
|
||||
label: 'OptionB',
|
||||
value: 'b'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
submitText: 'Submit'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
onSubmit: onSubmit
|
||||
},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
|
||||
await wait(200);
|
||||
fireEvent.click(getByText(/Submit/));
|
||||
await wait(200);
|
||||
|
||||
expect(onSubmit).toBeCalledTimes(1);
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchObject({
|
||||
aId: 123,
|
||||
a: 'a'
|
||||
});
|
||||
});
|
||||
|
||||
test('8. AutoFill initAutoFill true', async () => {
|
||||
const onSubmit = jest.fn();
|
||||
const {debug, container, getByText, findByText} = render(
|
||||
amisRender(
|
||||
{
|
||||
type: 'page',
|
||||
body: [
|
||||
{
|
||||
type: 'form',
|
||||
title: 'The form',
|
||||
controls: [
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'aId',
|
||||
value: 123
|
||||
},
|
||||
{
|
||||
type: 'hidden',
|
||||
name: 'bId'
|
||||
},
|
||||
{
|
||||
type: 'radios',
|
||||
name: 'a',
|
||||
autoFill: {
|
||||
aValue: '${value}',
|
||||
aLabel: '${label}',
|
||||
aId: '${id}',
|
||||
bId: '${id}'
|
||||
},
|
||||
initAutoFill: true,
|
||||
value: 'a',
|
||||
options: [
|
||||
{
|
||||
label: 'OptionA',
|
||||
value: 'a',
|
||||
id: 233
|
||||
},
|
||||
{
|
||||
label: 'OptionB',
|
||||
value: 'b'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
submitText: 'Submit'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
onSubmit: onSubmit
|
||||
},
|
||||
makeEnv()
|
||||
)
|
||||
);
|
||||
|
||||
await wait(200);
|
||||
fireEvent.click(getByText(/Submit/));
|
||||
await wait(200);
|
||||
|
||||
expect(onSubmit).toBeCalledTimes(1);
|
||||
expect(onSubmit.mock.calls[0][0]).toMatchObject({
|
||||
aId: 233,
|
||||
a: 'a',
|
||||
aValue: 'a',
|
||||
aLabel: 'OptionA',
|
||||
bId: 233
|
||||
});
|
||||
});
|
||||
|
@ -283,6 +283,7 @@ test('options:autoFill-merge', async () => {
|
||||
makeEnv({})
|
||||
)
|
||||
);
|
||||
await wait(200);
|
||||
|
||||
fireEvent.click(getByText('选项1'));
|
||||
await wait(300);
|
||||
|
Loading…
Reference in New Issue
Block a user