Skip to content

Commit

Permalink
fix(element): fix simple array key (#2024)
Browse files Browse the repository at this point in the history
  • Loading branch information
muuyao authored Aug 17, 2021
1 parent da058e6 commit 7e368d6
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<Form :form="form" label-align="left" :label-width="160">
<Form :form="form">
<SchemaField :schema="schema" />
<Submit @submit="onSubmit">提交</Submit>
</Form>
Expand Down
27 changes: 26 additions & 1 deletion packages/element/docs/demos/guide/time-picker/markup-schema.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
<template>
<FormProvider :form="form">
<SchemaField> </SchemaField>
<SchemaField>
<SchemaStringField
name="time"
title="时间"
required
x-decorator="FormItem"
x-component="TimePicker"
:x-component-props="{
style: {
width: '240px',
},
}"
/>
<SchemaStringField
name="[startTime, endTime]"
title="时间范围"
x-decorator="FormItem"
x-component="TimePicker"
:x-component-props="{
isRange: true,
style: {
width: '240px',
},
}"
/>
</SchemaField>
<Submit @submit="log">提交</Submit>
</FormProvider>
</template>
Expand Down
93 changes: 80 additions & 13 deletions packages/element/src/array-base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
inject,
toRefs,
ref,
onBeforeUnmount,
PropType,
} from '@vue/composition-api'
import { Fragment, useField, useFieldSchema, h } from '@formily/vue'
import { isValid, uid, clone } from '@formily/shared'
Expand Down Expand Up @@ -37,6 +39,7 @@ export type ArrayBaseMixins = {

export interface IArrayBaseProps {
disabled?: boolean
keyMap?: WeakMap<Object, String> | String[] | null
}

export interface IArrayBaseItemProps {
Expand All @@ -50,6 +53,7 @@ export interface IArrayBaseContext {
listeners: {
[key in string]?: Function
}
keyMap?: WeakMap<Object, String> | String[] | null
}

const ArrayBaseSymbol: InjectionKey<IArrayBaseContext> =
Expand All @@ -65,16 +69,45 @@ const useIndex = (index?: number) => {
return indexRef ?? ref(index)
}

const useKey = () => {
const keyMap = new WeakMap()
const isObjectValue = (schema: Schema) => {
if (Array.isArray(schema?.items)) return isObjectValue(schema.items[0])

return (record: any) => {
record =
record === null || typeof record !== 'object' ? Object(record) : record
if (!keyMap.has(record)) {
keyMap.set(record, uid())
}
return keyMap.get(record)
if (schema?.items?.type === 'array' || schema?.items?.type === 'object') {
return true
}
return false
}

const useKey = (schema: Schema) => {
const isObject = isObjectValue(schema)
let keyMap: WeakMap<Object, String> | String[] | null = null

if (isObject) {
keyMap = new WeakMap()
} else {
keyMap = []
}

onBeforeUnmount(() => {
keyMap = null
})

return {
keyMap,
getKey: (record: any, index?: number) => {
if (keyMap instanceof WeakMap) {
if (!keyMap.has(record)) {
keyMap.set(record, uid())
}
return keyMap.get(record)
}

if (!keyMap[index]) {
keyMap[index] = uid()
}

return keyMap[index]
},
}
}

Expand All @@ -92,14 +125,28 @@ const getDefaultValue = (defaultValue: any, schema: Schema): any => {
return null
}

const ArrayBaseInner = defineComponent({
const ArrayBaseInner = defineComponent<IArrayBaseProps>({
name: 'ArrayBase',
props: ['disabled'],
setup(props: IArrayBaseProps, { slots, listeners }) {
props: {
disabled: {
type: Boolean,
default: false,
},
keyMap: {
type: [WeakMap, Array] as PropType<WeakMap<Object, String> | String[]>,
},
},
setup(props, { slots, listeners }) {
const field = useField<ArrayField>()
const schema = useFieldSchema()

provide(ArrayBaseSymbol, { field, schema, props, listeners })
provide(ArrayBaseSymbol, {
field,
schema,
props,
listeners,
keyMap: props.keyMap,
})
return () => {
return h(Fragment, {}, slots)
}
Expand Down Expand Up @@ -241,6 +288,10 @@ const ArrayBaseRemove = defineComponent<
...listeners,
click: (e: MouseEvent) => {
e.stopPropagation()
if (Array.isArray(base?.keyMap)) {
base?.keyMap?.splice(indexRef.value, 1)
}

base?.field.value.remove(indexRef.value as number)
base?.listeners?.remove?.(indexRef.value as number)

Expand Down Expand Up @@ -283,6 +334,14 @@ const ArrayBaseMoveDown = defineComponent<
...listeners,
click: (e: MouseEvent) => {
e.stopPropagation()
if (Array.isArray(base?.keyMap)) {
base.keyMap.splice(
indexRef.value + 1,
0,
base.keyMap.splice(indexRef.value, 1)[0]
)
}

base?.field.value.moveDown(indexRef.value as number)
base?.listeners?.moveDown?.(indexRef.value as number)

Expand Down Expand Up @@ -325,6 +384,14 @@ const ArrayBaseMoveUp = defineComponent<
...listeners,
click: (e: MouseEvent) => {
e.stopPropagation()
if (Array.isArray(base?.keyMap)) {
base.keyMap.splice(
indexRef.value - 1,
0,
base.keyMap.splice(indexRef.value, 1)[0]
)
}

base?.field.value.moveUp(indexRef.value as number)
base?.listeners?.moveUp?.(indexRef.value as number)

Expand Down
14 changes: 9 additions & 5 deletions packages/element/src/array-cards/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@ const ArrayCardsInner = observer(
const fieldRef = useField<ArrayField>()
const schemaRef = useFieldSchema()
const prefixCls = `${stylePrefix}-array-cards`
const getKey = ArrayBase.useKey()
const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)

return () => {
const field = fieldRef.value
const schema = schemaRef.value
const dataSource = Array.isArray(field.value) ? field.value.slice() : []

const dataSource = Array.isArray(field.value) ? field.value : []
if (!schema) throw new Error('can not found schema object')

const renderItems = () => {
Expand Down Expand Up @@ -123,10 +122,11 @@ const ArrayCardsInner = observer(
},
{}
)

return h(
ArrayBase.Item,
{
key: getKey(item),
key: getKey(item, index),
props: {
index,
},
Expand Down Expand Up @@ -214,7 +214,11 @@ const ArrayCardsInner = observer(
default: () =>
h(
ArrayBase,
{},
{
props: {
keyMap,
},
},
{
default: () => [
renderEmpty(),
Expand Down
9 changes: 6 additions & 3 deletions packages/element/src/array-collapse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const ArrayCollapseInner = observer(
}
})

const getKey = ArrayBase.useKey()
const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)

return () => {
const field = fieldRef.value
Expand All @@ -126,7 +126,7 @@ export const ArrayCollapseInner = observer(
const items = Array.isArray(schema.items)
? schema.items[index] || schema.items[0]
: schema.items
const key = getKey(item)
const key = getKey(item, index)
const panelProps = field
.query(`${field.address}.${index}`)
.get('componentProps')
Expand Down Expand Up @@ -334,6 +334,9 @@ export const ArrayCollapseInner = observer(
h(
ArrayBase,
{
props: {
keyMap,
},
on: {
add: (index: number) => {
activeKeys.value = insertActiveKeys(
Expand Down Expand Up @@ -367,7 +370,7 @@ export const ArrayCollapseItem = defineComponent<CollapseItemProps>({
})

export const ArrayCollapse = composeExport(ArrayCollapseInner, {
collapseItem: ArrayCollapseItem,
Item: ArrayCollapseItem,
Index: ArrayBase.Index,
SortHandle: ArrayBase.SortHandle,
Addition: ArrayBase.Addition,
Expand Down
19 changes: 14 additions & 5 deletions packages/element/src/array-items/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const ArrayItemsInner = observer(
const schemaRef = useFieldSchema()

const prefixCls = `${stylePrefix}-array-items`
const getKey = ArrayBase.useKey()
const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)

return () => {
const field = fieldRef.value
Expand All @@ -36,7 +36,7 @@ const ArrayItemsInner = observer(
const items = Array.isArray(schema.items)
? schema.items[index] || schema.items[0]
: schema.items
const key = getKey(item)
const key = getKey(item, index)
return h(
ArrayBase.Item,
{
Expand Down Expand Up @@ -82,10 +82,15 @@ const ArrayItemsInner = observer(
useDragHandle: true,
lockAxis: 'y',
helperClass: `${prefixCls}-sort-helper`,
onSortEnd: ({ oldIndex, newIndex }) => {
value: [],
},
on: {
'sort-end': ({ oldIndex, newIndex }) => {
if (Array.isArray(keyMap)) {
keyMap.splice(newIndex, 0, keyMap.splice(oldIndex, 1)[0])
}
field.move(oldIndex, newIndex)
},
value: [],
},
},
{ default: () => items }
Expand All @@ -111,7 +116,11 @@ const ArrayItemsInner = observer(

return h(
ArrayBase,
{},
{
props: {
keyMap,
},
},
{
default: () =>
h(
Expand Down
8 changes: 6 additions & 2 deletions packages/element/src/array-table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ const ArrayTableInner = observer(
const fieldRef = useField<ArrayField>()
const schemaRef = useFieldSchema()
const prefixCls = `${stylePrefix}-array-table`
const getKey = ArrayBase.useKey()
const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)

const defaultRowKey = (record: any) => {
return getKey(record)
Expand Down Expand Up @@ -496,7 +496,11 @@ const ArrayTableInner = observer(
default: () =>
h(
ArrayBase,
{},
{
props: {
keyMap,
},
},
{
default: () => [
h(
Expand Down

0 comments on commit 7e368d6

Please sign in to comment.