refactor: Typehinting improvals, moved registry class, improved logic of shallow equal checker
This commit is contained in:
parent
e6271bb069
commit
7aca27a010
@ -16,7 +16,7 @@ import {
|
||||
Prop,
|
||||
Watch,
|
||||
} from 'vue-property-decorator'
|
||||
import { arrayify, has, shallowEqualObjects, snakeToCamel } from './utils'
|
||||
import { arrayify, has, shallowEquals, snakeToCamel } from './utils'
|
||||
import {
|
||||
processConstraints,
|
||||
validate,
|
||||
@ -102,7 +102,7 @@ export default class FormularioField extends Vue {
|
||||
private set model (value: unknown) {
|
||||
value = this.modelSetConverter(value, this.proxy)
|
||||
|
||||
if (!shallowEqualObjects(value, this.proxy)) {
|
||||
if (!shallowEquals(value, this.proxy)) {
|
||||
this.proxy = value
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ export default class FormularioField extends Vue {
|
||||
|
||||
@Watch('proxy')
|
||||
private onProxyChange (newValue: unknown, oldValue: unknown): void {
|
||||
if (!this.hasModel && !shallowEqualObjects(newValue, oldValue)) {
|
||||
if (!this.hasModel && !shallowEquals(newValue, oldValue)) {
|
||||
this.context.model = newValue
|
||||
}
|
||||
if (this.validationBehavior === VALIDATION_BEHAVIOR.LIVE) {
|
||||
@ -165,7 +165,7 @@ export default class FormularioField extends Vue {
|
||||
|
||||
@Watch('value')
|
||||
private onValueChange (newValue: unknown, oldValue: unknown): void {
|
||||
if (this.hasModel && !shallowEqualObjects(newValue, oldValue)) {
|
||||
if (this.hasModel && !shallowEquals(newValue, oldValue)) {
|
||||
this.context.model = newValue
|
||||
}
|
||||
}
|
||||
@ -199,14 +199,14 @@ export default class FormularioField extends Vue {
|
||||
private initProxy (): void {
|
||||
// This should only be run immediately on created and ensures that the
|
||||
// proxy and the model are both the same before any additional registration.
|
||||
if (!shallowEqualObjects(this.context.model, this.proxy)) {
|
||||
if (!shallowEquals(this.context.model, this.proxy)) {
|
||||
this.context.model = this.proxy
|
||||
}
|
||||
}
|
||||
|
||||
runValidation (): Promise<void> {
|
||||
runValidation (): Promise<Violation[]> {
|
||||
this.validationRun = this.validate().then(violations => {
|
||||
const validationChanged = !shallowEqualObjects(violations, this.violations)
|
||||
const validationChanged = !shallowEquals(violations, this.violations)
|
||||
this.violations = violations
|
||||
if (validationChanged) {
|
||||
const payload = {
|
||||
@ -221,6 +221,7 @@ export default class FormularioField extends Vue {
|
||||
|
||||
return this.violations
|
||||
})
|
||||
|
||||
return this.validationRun
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,10 @@ import {
|
||||
has,
|
||||
merge,
|
||||
setNested,
|
||||
shallowEqualObjects,
|
||||
shallowEquals,
|
||||
} from '@/utils'
|
||||
|
||||
import Registry from '@/form/registry'
|
||||
import FormularioFormRegistry from '@/FormularioFormRegistry'
|
||||
|
||||
import FormularioField from '@/FormularioField.vue'
|
||||
|
||||
@ -54,7 +54,7 @@ export default class FormularioForm extends Vue {
|
||||
|
||||
public proxy: Record<string, unknown> = {}
|
||||
|
||||
private registry: Registry = new Registry(this)
|
||||
private registry: FormularioFormRegistry = new FormularioFormRegistry(this)
|
||||
|
||||
private errorObserverRegistry = new ErrorObserverRegistry()
|
||||
// Local error messages are temporal, they wiped each resetValidation call
|
||||
@ -174,12 +174,12 @@ export default class FormularioForm extends Vue {
|
||||
const oldValue = getNested(this.proxy, fqn)
|
||||
const newValue = getNested(values, fqn)
|
||||
|
||||
if (!shallowEqualObjects(newValue, oldValue)) {
|
||||
if (!shallowEquals(newValue, oldValue)) {
|
||||
this.setFieldValue(fqn, newValue)
|
||||
proxyHasChanges = true
|
||||
}
|
||||
|
||||
if (!shallowEqualObjects(newValue, $field.proxy)) {
|
||||
if (!shallowEquals(newValue, $field.proxy)) {
|
||||
$field.context.model = newValue
|
||||
}
|
||||
})
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { shallowEqualObjects, has, getNested } from '@/utils'
|
||||
import { getNested, has, shallowEquals } from '@/utils'
|
||||
|
||||
import FormularioField from '@/FormularioField.vue'
|
||||
import FormularioForm from '@/FormularioForm.vue'
|
||||
|
||||
@ -6,7 +7,7 @@ import FormularioForm from '@/FormularioForm.vue'
|
||||
* Component registry with inherent depth to handle complex nesting. This is
|
||||
* important for features such as grouped fields.
|
||||
*/
|
||||
export default class Registry {
|
||||
export default class FormularioFormRegistry {
|
||||
private ctx: FormularioForm
|
||||
private registry: Map<string, FormularioField>
|
||||
|
||||
@ -42,7 +43,7 @@ export default class Registry {
|
||||
// @ts-ignore
|
||||
component.context.model = value
|
||||
// @ts-ignore
|
||||
} else if (hasModel && !shallowEqualObjects(component.proxy, value)) {
|
||||
} else if (hasModel && !shallowEquals(component.proxy, value)) {
|
||||
// In this case, the field is v-modeled or has an initial value and the
|
||||
// form has no value or a different value, so use the field value
|
||||
// @ts-ignore
|
@ -4,7 +4,7 @@ export { default as has } from './has'
|
||||
export { isScalar } from './types'
|
||||
export { default as merge } from './merge'
|
||||
export { default as regexForFormat } from './regexForFormat'
|
||||
export { default as shallowEqualObjects } from './shallowEqualObjects'
|
||||
export { default as shallowEquals } from './shallowEquals'
|
||||
export { default as snakeToCamel } from './snakeToCamel'
|
||||
|
||||
export function getNested (obj: Record<string, any>, field: string): any {
|
||||
|
@ -1,34 +0,0 @@
|
||||
export default function shallowEqualObjects (objA: Record<string, any>, objB: Record<string, any>): boolean {
|
||||
if (objA === objB) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (!objA || !objB) {
|
||||
return false
|
||||
}
|
||||
|
||||
const aKeys = Object.keys(objA)
|
||||
const bKeys = Object.keys(objB)
|
||||
|
||||
if (bKeys.length !== aKeys.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (objA instanceof Date && objB instanceof Date) {
|
||||
return objA.getTime() === objB.getTime()
|
||||
}
|
||||
|
||||
if (aKeys.length === 0) {
|
||||
return objA === objB
|
||||
}
|
||||
|
||||
for (let i = 0; i < aKeys.length; i++) {
|
||||
const key = aKeys[i]
|
||||
|
||||
if (objA[key] !== objB[key]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
42
src/utils/shallowEquals.ts
Normal file
42
src/utils/shallowEquals.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export function equalsDates (a: Date, b: Date): boolean {
|
||||
return a.getTime() === b.getTime()
|
||||
}
|
||||
|
||||
export function shallowEqualsRecords (
|
||||
a: Record<string, unknown>,
|
||||
b: Record<string, unknown>
|
||||
): boolean {
|
||||
const aKeys = Object.keys(a)
|
||||
const bKeys = Object.keys(b)
|
||||
|
||||
if (aKeys.length !== bKeys.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (aKeys.length === 0) {
|
||||
return a === b
|
||||
}
|
||||
|
||||
return aKeys.reduce((equals: boolean, key: string): boolean => {
|
||||
return equals && a[key] === b[key]
|
||||
}, true)
|
||||
}
|
||||
|
||||
export default function shallowEquals (a: unknown, b: unknown): boolean {
|
||||
if (a === b) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (!a || !b) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (a instanceof Date && b instanceof Date) {
|
||||
return equalsDates(a, b)
|
||||
}
|
||||
|
||||
return shallowEqualsRecords(
|
||||
a as Record<string, unknown>,
|
||||
b as Record<string, unknown>
|
||||
)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import isUrl from 'is-url'
|
||||
import { has, regexForFormat, shallowEqualObjects } from '@/utils'
|
||||
import { has, regexForFormat, shallowEquals } from '@/utils'
|
||||
import {
|
||||
ValidationContext,
|
||||
ValidationRuleFn,
|
||||
@ -130,7 +130,7 @@ const rules: Record<string, ValidationRuleFn> = {
|
||||
* Rule: Value is in an array (stack).
|
||||
*/
|
||||
in ({ value }: ValidationContext, ...stack: any[]): boolean {
|
||||
return stack.some(item => typeof item === 'object' ? shallowEqualObjects(item, value) : item === value)
|
||||
return stack.some(item => typeof item === 'object' ? shallowEquals(item, value) : item === value)
|
||||
},
|
||||
|
||||
/**
|
||||
@ -198,7 +198,7 @@ const rules: Record<string, ValidationRuleFn> = {
|
||||
* Rule: Value is not in stack.
|
||||
*/
|
||||
not ({ value }: ValidationContext, ...stack: any[]): boolean {
|
||||
return !stack.some(item => typeof item === 'object' ? shallowEqualObjects(item, value) : item === value)
|
||||
return !stack.some(item => typeof item === 'object' ? shallowEquals(item, value) : item === value)
|
||||
},
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user