Skip to content

Commit

Permalink
fix(Field): cache parseName values
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkahn committed Jun 24, 2019
1 parent 4225efe commit 6c6ca04
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 27 deletions.
26 changes: 19 additions & 7 deletions src/field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
getParams,
setIn,
getIn,
deleteIn,
mapValidateRules,
} from './utils';

Expand All @@ -29,7 +30,9 @@ class Field {
this.fieldsMeta = {};
this.cachedBind = {};
this.instance = {};
this.initValue = options.values || {};
// holds constructor values. Used for setting field defaults on init if no other value or initValue is passed.
// Also used caching values when using `parseName: true` before a field is initialized
this.fieldCache = options.values || {};

this.options = Object.assign(
{
Expand Down Expand Up @@ -101,10 +104,10 @@ class Field {
} else if (originalProps[defaultValueName]) {
defaultValue = originalProps[defaultValueName];
} else if (this.options.parseName) {
defaultValue = getIn(this.initValue, name);
defaultValue = getIn(this.fieldCache, name);
} else {
defaultValue =
(this.initValue && this.initValue[name]) || undefined;
(this.fieldCache && this.fieldCache[name]) || undefined;
}

Object.assign(field, {
Expand Down Expand Up @@ -318,7 +321,11 @@ class Field {
return field.value;
}

return getIn(this.initValue, name);
if (this.options.parseName) {
return getIn(this.fieldCache, name);
}

return undefined;
}

/**
Expand All @@ -342,8 +349,8 @@ class Field {
allValues = setIn(allValues, name, this.getValue(name));
}
});
} else if (this.initValue) {
allValues = this.initValue;
} else if (this.options.parseName) {
allValues = this.fieldCache;
}

return allValues;
Expand All @@ -367,6 +374,8 @@ class Field {
this.setValue(name, fieldsValue[name], false);
});
} else {
// set fieldCache to be used later. If no fields were initialized, this is used for getValue
this.fieldCache = Object.assign({}, this.fieldCache, fieldsValue);
const fields = this.getNames();
fields.forEach(name => {
const value = getIn(fieldsValue, name);
Expand Down Expand Up @@ -594,7 +603,6 @@ class Field {
const names = ns || Object.keys(this.fieldsMeta);
names.forEach(name => {
const field = this._get(name);
this.getValue(name);
if (field) {
changed = true;

Expand Down Expand Up @@ -647,11 +655,15 @@ class Field {
if (typeof ns === 'string') {
ns = [ns];
}
if (!ns) {
this.fieldCache = {};
}
const names = ns || Object.keys(this.fieldsMeta);
names.forEach(name => {
if (name in this.fieldsMeta) {
delete this.fieldsMeta[name];
}
deleteIn(this.fieldCache, name);
});
}

Expand Down
26 changes: 26 additions & 0 deletions src/field/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,32 @@ export function getIn(state, name) {
return result;
}

export function deleteIn(state, name) {
if (!state) {
return;
}

const path = name
.replace(/\[/, '.')
.replace(/\]/, '')
.split('.');
const length = path.length;
if (!length) {
return;
}

let result = state;
for (let i = 0; i < length && !!result; ++i) {
if (i === length - 1) {
delete result[path[i]];
} else {
result = result[path[i]];
}
}

return state;
}

function validateMap(rulesMap, rule, defaultTrigger) {
const nrule = Object.assign({}, rule);

Expand Down
36 changes: 36 additions & 0 deletions test/field/index-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,42 @@ describe('field', () => {
done();
});

it('should return `undefined` for `getValue` on uninitialized field', function() {
const field = new Field(this);
assert.equal(field.getValue('input'), undefined);
});

it('should return empty object for `getValues` on uninitialized field', function() {
const field = new Field(this);
assert.equal(Object.keys(field.getValues()).length, 0);
});

it('should set value with `setValue` on uninitialized field', function() {
const field = new Field(this);
field.setValue('input', 1)
field.init('input');
assert.equal(field.getValue('input'), 1);
});

it('should set value with `setValues` on uninitialized field', function() {
const field = new Field(this);
field.setValues({input: 1})
field.init('input');
assert.equal(field.getValue('input'), 1);
});

it('should return value from `setValue` when calling `getValue` on uninitialized field', function() {
const field = new Field(this);
field.setValue('input', 1)
assert.equal(field.getValue('input'), 1);
});

it('should return value from `setValue` when calling `getValues` on uninitialized field', function() {
const field = new Field(this);
field.setValue('input', 1)
assert.equal(field.getValues().input, 1);
});

it('should ignore disabled values when calling getValues', function() {
const field = new Field(this);
field.init('input', { initValue: 1, props: { disabled: true} });
Expand Down
Loading

0 comments on commit 6c6ca04

Please sign in to comment.