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): make exchangeArrayState be right when move #2357

Merged
merged 2 commits into from
Oct 27, 2021
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
58 changes: 57 additions & 1 deletion packages/core/src/__tests__/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,61 @@ test('array field children state exchanges', () => {
expect(form.query('array.2.value').get('value')).toEqual(55)
})

test('array field move up/down then fields move', () => {
const form = attach(createForm())
const array = attach(
form.createArrayField({
name: 'array',
})
)
attach(
form.createField({
name: 'value',
basePath: 'array.0',
})
)
attach(
form.createField({
name: 'value',
basePath: 'array.1',
})
)
attach(
form.createField({
name: 'value',
basePath: 'array.2',
})
)
attach(
form.createField({
name: 'value',
basePath: 'array.3',
})
)
const line0 = form.fields['array.0.value']
const line1 = form.fields['array.1.value']
const line2 = form.fields['array.2.value']
const line3 = form.fields['array.3.value']

array.push({ value: '0' }, { value: '1' }, { value: '2' }, { value: '3' })

array.move(0, 3)

// 1,2,3,0
expect(form.fields['array.0.value']).toBe(line1)
expect(form.fields['array.1.value']).toBe(line2)
expect(form.fields['array.2.value']).toBe(line3)
expect(form.fields['array.3.value']).toBe(line0)

array.move(3, 1)

// 1,0,2,3
expect(form.fields['array.0.value']).toBe(line1)
expect(form.fields['array.1.value']).toBe(line0)
expect(form.fields['array.2.value']).toBe(line2)
expect(form.fields['array.3.value']).toBe(line3)
})

test('void children', () => {
const form = attach(createForm())
const array = attach(
Expand Down Expand Up @@ -356,8 +411,9 @@ test('array field move api with children', async () => {
})
)
await array.move(0, 2)
expect(form.fields['array.0.name']).not.toBeUndefined()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么要删掉呢?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个单元测试是之前的 交换 的逻辑,实际应该验证的逻辑是现在的,插入后再移动

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 -> 2,原先是 0, 1, 2(name),就变成 1, 2(name), 0,所以测试应该是 0 和 2 位没有,1 位有

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的

expect(form.fields['array.0.name']).toBeUndefined()
expect(form.fields['array.2.name']).toBeUndefined()
expect(form.fields['array.1.name']).not.toBeUndefined()
})

test('array field remove memo leak', async () => {
Expand Down
20 changes: 16 additions & 4 deletions packages/core/src/shared/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,12 +423,24 @@ export const exchangeArrayState = (
return identifier.indexOf(address) === 0 && identifier.length > addrLength
}

const isFromOrToNode = (identifier: string) => {
const isDown = fromIndex < toIndex

const isMoveNode = (identifier: string) => {
const afterStr = identifier.slice(address.length)
const number = afterStr.match(NumberIndexReg)?.[1]
if (number === undefined) return false
const index = Number(number)
return isDown
? index > fromIndex && index <= toIndex
: index < fromIndex && index >= toIndex
}

const isFromNode = (identifier: string) => {
const afterStr = identifier.substring(addrLength)
const number = afterStr.match(NumberIndexReg)?.[1]
if (number === undefined) return false
const index = Number(number)
return index === toIndex || index === fromIndex
return index === fromIndex
}

const moveIndex = (identifier: string) => {
Expand All @@ -440,7 +452,7 @@ export const exchangeArrayState = (
if (index === fromIndex) {
index = toIndex
} else {
index = fromIndex
index += isDown ? -1 : 1
}

return `${preStr}${afterStr.replace(/^\.\d+/, `.${index}`)}`
Expand All @@ -449,7 +461,7 @@ export const exchangeArrayState = (
batch(() => {
each(fields, (field, identifier) => {
if (isArrayChildren(identifier)) {
if (isFromOrToNode(identifier)) {
if (isMoveNode(identifier) || isFromNode(identifier)) {
const newIdentifier = moveIndex(identifier)
fieldPatches.push({
type: 'update',
Expand Down