From 708639c57f2386635b926f666a6b452789e5828c Mon Sep 17 00:00:00 2001 From: Sagi Date: Wed, 28 Feb 2024 00:00:33 +0800 Subject: [PATCH] fix: clear display text while clear model value on combo list --- .../combo-list/src/combo-list.component.tsx | 23 ++- .../combo-list/src/composition/types.ts | 6 +- .../src/composition/use-data-source.ts | 41 ++++-- packages/ui-vue/demos/combo-list/cascade.vue | 139 ++++++++++++++++++ packages/ui-vue/src/app.vue | 2 + 5 files changed, 192 insertions(+), 19 deletions(-) create mode 100644 packages/ui-vue/demos/combo-list/cascade.vue diff --git a/packages/ui-vue/components/combo-list/src/combo-list.component.tsx b/packages/ui-vue/components/combo-list/src/combo-list.component.tsx index f39fe9b3d8..83e35ddd20 100644 --- a/packages/ui-vue/components/combo-list/src/combo-list.component.tsx +++ b/packages/ui-vue/components/combo-list/src/combo-list.component.tsx @@ -27,7 +27,7 @@ export default defineComponent({ emits: ['clear', 'update:modelValue', 'change'] as (string[] & ThisType) | undefined, setup(props: ComboListProps, context: SetupContext) { const comboEditorRef: Ref = ref(); - const { dataSource, displayText, modelValue, getItemsByDisplayText } = useDataSource(props); + const { dataSource, displayText, editable, modelValue, getItemsByDisplayText } = useDataSource(props); const isMultiSelect = computed(() => props.multiSelect); @@ -52,11 +52,30 @@ export default defineComponent({ context.emit('clear'); } + function onTextChanged(displayText: string) { + modelValue.value = displayText; + context.emit('update:modelValue', modelValue.value); + const changedValue = {} as Record; + changedValue[props.idField] = displayText; + changedValue[props.textField] = displayText; + context.emit('change', [changedValue]); + } + function onDisplayTextChange(displayText: string) { + if (editable.value) { + onTextChanged(displayText); + return; + } const items = getItemsByDisplayText(displayText); onSelectionChange(items); } + function getDisplayText() { + return displayText.value; + } + + context.expose({ getDisplayText }); + return () => { return ( ; + displayText: Ref; - modelValue: Ref; + editable: Ref; - dataSource: Ref; + modelValue: Ref; getItemsByDisplayText: (text: string) => Option[]; diff --git a/packages/ui-vue/components/combo-list/src/composition/use-data-source.ts b/packages/ui-vue/components/combo-list/src/composition/use-data-source.ts index aa2e22f27f..b21c36d6d0 100644 --- a/packages/ui-vue/components/combo-list/src/composition/use-data-source.ts +++ b/packages/ui-vue/components/combo-list/src/composition/use-data-source.ts @@ -6,19 +6,7 @@ export function useDataSource(props: ComboListProps): UseDataSource { const displayText = ref(''); const modelValue = ref(props.modelValue); const dataSource = ref(props.data || []); - - watch(() => props.data, () => { - dataSource.value = props.data; - }); - - watch([dataSource], ([dataSourceValue]) => { - if (props.modelValue) { - const currentItem = dataSourceValue.find((item: any) => item[props.valueField] === props.modelValue); - if (currentItem) { - displayText.value = currentItem[props.textField]; - } - } - }); + const editable = ref(props.editable); function getItemsByValue(value: string): Option[] { const valueArray = value.split(props.separator).map<[string, boolean]>((valueText: string) => { @@ -28,7 +16,10 @@ export function useDataSource(props: ComboListProps): UseDataSource { return dataSource.value.filter((item: Option) => valueMap.has(item[props.valueField])); } - displayText.value = getItemsByValue(modelValue.value).map((item: Option) => item[props.textField]).join(props.separator); + function updateDisplayTextByValue(value: string) { + const matchedValue = getItemsByValue(value).map((item: Option) => item[props.textField]).join(props.separator); + displayText.value = editable.value ? (matchedValue || value) : matchedValue; + } function getItemsByDisplayText(text: string): Option[] { const displayTextArray = text.split(props.separator).map<[string, boolean]>((optionText: string) => { @@ -61,5 +52,25 @@ export function useDataSource(props: ComboListProps): UseDataSource { loadRemoteData(); } - return { dataSource, displayText, modelValue, getItemsByDisplayText, getItemsByValue }; + watch(() => props.data, () => { + dataSource.value = props.data; + }); + + watch([dataSource], ([dataSourceValue]) => { + if (props.modelValue) { + const currentItem = dataSourceValue.find((item: any) => item[props.valueField] === props.modelValue); + if (currentItem) { + displayText.value = currentItem[props.textField]; + } + } + }); + + watch(() => props.modelValue, (newValue) => { + modelValue.value = newValue; + updateDisplayTextByValue(newValue); + }); + + updateDisplayTextByValue(props.modelValue); + + return { dataSource, displayText, editable, modelValue, getItemsByDisplayText, getItemsByValue }; } diff --git a/packages/ui-vue/demos/combo-list/cascade.vue b/packages/ui-vue/demos/combo-list/cascade.vue new file mode 100644 index 0000000000..e8dc21d9a0 --- /dev/null +++ b/packages/ui-vue/demos/combo-list/cascade.vue @@ -0,0 +1,139 @@ + + + + diff --git a/packages/ui-vue/src/app.vue b/packages/ui-vue/src/app.vue index 209abad86e..31dc71a623 100644 --- a/packages/ui-vue/src/app.vue +++ b/packages/ui-vue/src/app.vue @@ -8,6 +8,7 @@ import CalendarBasic from '../demos/calendar/basic.vue'; import CapsuleBasic from '../demos/capsule/basic.vue'; import ColorPickerBasic from '../demos/color-picker/basic.vue'; import ComboListBasic from '../demos/combo-list/basic.vue'; +import ComboListCascade from '../demos/combo-list/cascade.vue'; import DataGridBasic from '../demos/data-grid/basic.vue'; import DataGridBindingLocalData from '../demos/data-grid/binding_local_data.vue'; import DataGridPageLocalData from '../demos/data-grid/page_local_data.vue'; @@ -84,6 +85,7 @@ const routes: Record = { '/capsule/basic': CapsuleBasic, '/color-picker/basic': ColorPickerBasic, '/combo-list/basic': ComboListBasic, + '/combo-list/cascade': ComboListCascade, '/data-grid/basic': DataGridBasic, '/data-grid/binding_local_data': DataGridBindingLocalData, '/data-grid/page_local_data': DataGridPageLocalData, -- Gitee