Skip to content

Commit

Permalink
fix(core): fix relative match can not skip void field (#2850)
Browse files Browse the repository at this point in the history
  • Loading branch information
janryWang committed Feb 23, 2022
1 parent ec2ee6d commit e7c9984
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 16 deletions.
28 changes: 28 additions & 0 deletions packages/core/src/__tests__/field.spec.ts
Expand Up @@ -1974,3 +1974,31 @@ test('query value with sibling path syntax', () => {
textarea.value = '123'
expect(fn).toBeCalledWith('123', 'aaa')
})

test('relative query with void field', () => {
const form = attach(createForm())
attach(
form.createVoidField({
name: 'void',
})
)
const aa = attach(
form.createField({
name: 'aa',
basePath: 'void',
})
)
attach(
form.createVoidField({
name: 'mm',
})
)
const bb = attach(
form.createField({
name: 'bb',
basePath: 'mm',
})
)

expect(bb.query('.aa').take()).toBe(aa)
})
29 changes: 21 additions & 8 deletions packages/core/src/models/Query.ts
@@ -1,4 +1,5 @@
import { FormPath, isFn, each, FormPathPattern } from '@formily/shared'
import { buildDataPath } from '../shared/internals'
import { GeneralField, IGeneralFieldState, IQueryProps } from '../types'
import { Form } from './Form'

Expand All @@ -13,6 +14,18 @@ const output = (
return field
}

const takeMatchPattern = (form: Form, pattern: FormPath) => {
const identifier = pattern.toString()
const indexIdentifier = form.indexes[identifier]
const absoluteField = form.fields[identifier]
const indexField = form.fields[indexIdentifier]
if (absoluteField) {
return identifier
} else if (indexField) {
return indexIdentifier
}
}

export class Query {
private pattern: FormPath
private addresses: string[] = []
Expand All @@ -21,14 +34,14 @@ export class Query {
this.pattern = FormPath.parse(props.pattern, props.base)
this.form = props.form
if (!this.pattern.isMatchPattern) {
const identifier = this.pattern.toString()
const indexIdentifier = this.form.indexes[identifier]
const absoluteField = this.form.fields[identifier]
const indexField = this.form.fields[indexIdentifier]
if (absoluteField) {
this.addresses = [identifier]
} else if (indexField) {
this.addresses = [indexIdentifier]
const matched = takeMatchPattern(
this.form,
this.pattern.haveRelativePattern
? buildDataPath(props.form.fields, this.pattern)
: this.pattern
)
if (matched) {
this.addresses = [matched]
}
} else {
each(this.form.fields, (field, address) => {
Expand Down
13 changes: 8 additions & 5 deletions packages/core/src/shared/internals.ts
Expand Up @@ -106,9 +106,15 @@ export const getTypedDefaultValue = (field: Field) => {
}

export const buildFieldPath = (field: GeneralField) => {
return buildDataPath(field.form.fields, field.address)
}

export const buildDataPath = (
fields: Record<string, GeneralField>,
pattern: FormPath
) => {
let prevArray = false
const fields = field.form.fields
const segments = field.address.segments
const segments = pattern.segments
const path = segments.reduce((path: string[], key: string, index: number) => {
const currentPath = path.concat(key)
const currentAddress = segments.slice(0, index + 1)
Expand All @@ -120,9 +126,6 @@ export const buildFieldPath = (field: GeneralField) => {
return path
}
if (index >= segments.length - 1) {
if (isVoidField(field)) {
return currentPath
}
return currentPath
}
if (isVoidField(current)) {
Expand Down
9 changes: 9 additions & 0 deletions packages/path/src/index.ts
Expand Up @@ -133,6 +133,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
entire: pattern.entire,
segments: pattern.segments.slice(),
isRegExp: false,
haveRelativePattern: pattern.haveRelativePattern,
isWildMatchPattern: pattern.isWildMatchPattern,
isMatchPattern: pattern.isMatchPattern,
haveExcludePattern: pattern.haveExcludePattern,
Expand All @@ -157,6 +158,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
segments,
tree,
isRegExp: false,
haveRelativePattern: parser.haveRelativePattern,
isWildMatchPattern: false,
haveExcludePattern: false,
isMatchPattern: false,
Expand All @@ -166,6 +168,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
entire: pattern,
segments: [],
isRegExp: false,
haveRelativePattern: false,
isWildMatchPattern: parser.isWildMatchPattern,
haveExcludePattern: parser.haveExcludePattern,
isMatchPattern: true,
Expand All @@ -181,6 +184,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
return buf.concat(parseString(key))
}, []),
isRegExp: false,
haveRelativePattern: false,
isWildMatchPattern: false,
haveExcludePattern: false,
isMatchPattern: false,
Expand All @@ -190,6 +194,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
entire: pattern,
segments: [],
isRegExp: true,
haveRelativePattern: false,
isWildMatchPattern: false,
haveExcludePattern: false,
isMatchPattern: true,
Expand All @@ -199,6 +204,7 @@ const parse = (pattern: Pattern, base?: Pattern) => {
entire: '',
isRegExp: false,
segments: pattern !== undefined ? [pattern] : [],
haveRelativePattern: false,
isWildMatchPattern: false,
haveExcludePattern: false,
isMatchPattern: false,
Expand Down Expand Up @@ -227,6 +233,7 @@ export class Path {
public isMatchPattern: boolean
public isWildMatchPattern: boolean
public isRegExp: boolean
public haveRelativePattern: boolean
public haveExcludePattern: boolean
public matchScore: number
public tree: Node
Expand All @@ -241,12 +248,14 @@ export class Path {
isRegExp,
isMatchPattern,
isWildMatchPattern,
haveRelativePattern,
haveExcludePattern,
} = parse(input, base)
this.entire = entire
this.segments = segments
this.isMatchPattern = isMatchPattern
this.isWildMatchPattern = isWildMatchPattern
this.haveRelativePattern = haveRelativePattern
this.isRegExp = isRegExp
this.haveExcludePattern = haveExcludePattern
this.tree = tree as Node
Expand Down
9 changes: 6 additions & 3 deletions packages/path/src/parser.ts
Expand Up @@ -75,11 +75,13 @@ const calculate = (
}

export class Parser extends Tokenizer {
public isMatchPattern: boolean
public isMatchPattern = false

public isWildMatchPattern: boolean
public isWildMatchPattern = false

public haveExcludePattern: boolean
public haveExcludePattern = false

public haveRelativePattern = false

public base: Path

Expand Down Expand Up @@ -353,6 +355,7 @@ export class Parser extends Tokenizer {
this.data.segments = this.base.toArr()
while (this.state.type === dotTok) {
this.relative = this.data.segments.pop()
this.haveRelativePattern = true
this.next()
}
return createTreeBySegments(
Expand Down

0 comments on commit e7c9984

Please sign in to comment.