Skip to content

Commit

Permalink
fix(Field): parseName defaults (alibaba-fusion#683)
Browse files Browse the repository at this point in the history
* fix(Field): parseName defaults
- field constructor saves passed values
- field init looks at constructor values for defaults
  • Loading branch information
jdkahn authored and youluna committed May 21, 2019
1 parent 8b78283 commit 7fe0130
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 49 deletions.
74 changes: 74 additions & 0 deletions docs/field/demo/topath-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 结构化解析

- order: 12

使用 parseName 时设置默认值。
输入名称是 “值” 道具内的路径

:::lang=en-us
# Parse Array or Object

- order: 12

Set default values when using parseName.
Input name is path inside `values` prop

:::
---

````jsx
import {Input, Button, Field, Form } from '@alifd/next';



class Demo extends React.Component {
field = new Field(this, {
parseName: true,
values: {
aaa: ['xxx', 'yyy'],
bbb: {
ccc: 'value c'
}
}
});

_handleValidate = () => {
const {
field: {
validate
}
} = this;

validate(['bbb.ccc'])
};

render() {
const {
field,
field: {
init,
}
} = this;

console.log(this)

return <Form field={field}>
<Button onClick={this._handleValidate}>validate</Button>
<Form.Item label="aaa" key="aaa">
<Input name="aaa.0"/>
</Form.Item>
<Form.Item label="ccc" key="ccc">
<Input name="bbb.ccc"/>
</Form.Item>
</Form>;
}
}

ReactDOM.render(<Demo/>, mountNode);
````

````css
.demo .next-btn {
margin-right: 5px;
}
````
17 changes: 9 additions & 8 deletions src/field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Field {
this.fieldsMeta = {};
this.cachedBind = {};
this.instance = {};
this.initValues = options.values || {};

this.options = Object.assign(
{
Expand Down Expand Up @@ -62,10 +63,6 @@ class Field {
].forEach(m => {
this[m] = this[m].bind(this);
});

if (options.values) {
this.setValues(options.values, false);
}
}

setOptions(options) {
Expand Down Expand Up @@ -94,10 +91,14 @@ class Field {
)}`;

const field = this._getInitMeta(name);
const defaultValue =
typeof initValue !== 'undefined'
? initValue
: originalProps[defaultValueName];
let defaultValue;
if (typeof initValue !== 'undefined') {
defaultValue = initValue;
} else if (originalProps[defaultValueName]) {
defaultValue = originalProps[defaultValueName];
} else {
defaultValue = getIn(this.initValues, name);
}

Object.assign(field, {
valueName,
Expand Down
65 changes: 33 additions & 32 deletions test/field/index-spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable react/no-multi-comp */
import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Expand Down Expand Up @@ -158,11 +159,11 @@ describe('field', () => {
});
describe('init', () => {
it('init(input)', function(done) {
let field = new Field(this);
let inited = field.init('input');
const field = new Field(this);
const inited = field.init('input');

assert(typeof inited['ref'] === 'function');
assert(inited['id'] === 'input');
assert(typeof inited.ref === 'function');
assert(inited.id === 'input');
assert(inited['data-meta'] === 'Field');
assert('onChange' in inited);

Expand All @@ -180,8 +181,8 @@ describe('field', () => {
done();
});
it('initValue', function(done) {
let field = new Field(this);
let inited = field.init('input', { initValue: 2 });
const field = new Field(this);
const inited = field.init('input', { initValue: 2 });

assert(inited.value === 2);
field.init('input', { initValue: 24 });
Expand All @@ -192,8 +193,8 @@ describe('field', () => {
done();
});
it('valueName', function(done) {
let field = new Field(this);
let inited = field.init('input', {
const field = new Field(this);
const inited = field.init('input', {
initValue: true,
valueName: 'checked',
});
Expand All @@ -203,8 +204,8 @@ describe('field', () => {
});

it('props', function(done) {
let field = new Field(this);
let inited = field.init('input', {
const field = new Field(this);
const inited = field.init('input', {
initValue: true,
valueName: 'checked',
props: {
Expand All @@ -220,8 +221,8 @@ describe('field', () => {

it('custom Event: onChange', function(done) {
const onChange = sinon.spy();
let field = new Field(this, { onChange });
let inited = field.init('input', {
const field = new Field(this, { onChange });
const inited = field.init('input', {
props: {
onChange,
},
Expand All @@ -236,7 +237,7 @@ describe('field', () => {
assert(field.getValue('input') === 'test');
assert(onChange.callCount === 2);

let field2 = new Field(this, {
const field2 = new Field(this, {
onChange: (name, value) => {
assert(value === 'test');
},
Expand All @@ -263,16 +264,16 @@ describe('field', () => {
});

it('getValueFromEvent', function(done) {
let field = new Field(this, {
const field = new Field(this, {
onChange: (name, value) => {
assert(value === 'test!');
},
});

let inited = field.init('input', {
const inited = field.init('input', {
getValueFromEvent: a => {
assert(a === 'test');
return a + '!';
return `${a }!`;
},
});

Expand All @@ -289,7 +290,7 @@ describe('field', () => {
});

it('rules', function(done) {
let field = new Field(this);
const field = new Field(this);
field.init('input', {
rules: [
{
Expand All @@ -314,7 +315,7 @@ describe('field', () => {

describe('behaviour', () => {
it('getValue & getValues & setValue & setValues', function(done) {
let field = new Field(this);
const field = new Field(this);
field.init('input', { initValue: 1 });
field.init('input2', { initValue: 2 });
field.init('input3.name', { initValue: 3 });
Expand All @@ -334,15 +335,15 @@ describe('field', () => {
});

it('setError & setErrors & getError & getErrors', function(done) {
let field = new Field(this);
const field = new Field(this);
field.setError('input', 'error1');

field.init('input');
field.init('input2');

field.setError('input', 'error1');
assert(field.getError('input')[0] === 'error1');
assert(field.getErrors(['input'])['input'][0] === 'error1');
assert(field.getErrors(['input']).input[0] === 'error1');

field.setError('input2', ['error2']);
assert(field.getError('input2')[0] === 'error2');
Expand All @@ -359,7 +360,7 @@ describe('field', () => {
done();
});
it('getState', function(done) {
let field = new Field(this);
const field = new Field(this);

field.init('input');

Expand All @@ -372,8 +373,8 @@ describe('field', () => {
});

it('validate', function(done) {
let field = new Field(this);
let inited = field.init('input', {
const field = new Field(this);
const inited = field.init('input', {
rules: [{ required: true, message: 'cant be null' }],
});

Expand All @@ -384,14 +385,14 @@ describe('field', () => {
},
});

field.validate((error, value, cb) => {
assert(error['input']['errors'][0] === 'cant be null');
field.validate((error) => {
assert(error.input.errors[0] === 'cant be null');
});
field.validate('input', (error, value, cb) => {
assert(error['input']['errors'][0] === 'cant be null');
field.validate('input', (error) => {
assert(error.input.errors[0] === 'cant be null');
});
field.validate(['input'], (error, value, cb) => {
assert(error['input']['errors'][0] === 'cant be null');
field.validate(['input'], (error) => {
assert(error.input.errors[0] === 'cant be null');
});

field.init('input2', {
Expand All @@ -416,7 +417,7 @@ describe('field', () => {
});

it('reset', function(done) {
let field = new Field(this);
const field = new Field(this);
field.init('input', { initValue: '1' });

field.reset();
Expand All @@ -431,7 +432,7 @@ describe('field', () => {
done();
});
it('remove', function(done) {
let field = new Field(this);
const field = new Field(this);
field.init('input', { initValue: 1 });
field.init('input2', { initValue: 1 });
field.init('input3', { initValue: 1 });
Expand All @@ -447,7 +448,7 @@ describe('field', () => {
done();
});
it('spliceArray', function(done) {
let field = new Field(this);
const field = new Field(this);
field.init('input.0', { initValue: 0 });
field.init('input.1', { initValue: 1 });
field.init('input.2', { initValue: 2 });
Expand Down
18 changes: 17 additions & 1 deletion test/field/options-spec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable react/jsx-filename-extension */
/* eslint-disable react/no-multi-comp */
import React from 'react';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Expand Down Expand Up @@ -155,7 +157,7 @@ describe('options', () => {
done();
});

it('values', function(done) {
it('should support default `values` in constructor', function(done) {
class Demo extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -188,6 +190,20 @@ describe('options', () => {
done();
});

it('should support default `values` in constructor when `parseName` = true', function() {
const inputValue = 'my value';
const field = new Field(this, {
parseName: true,
values: {
input: {
child: inputValue
}
}
});
field.init('input.child');
assert.equal(field.getValue('input.child'), inputValue);
});

describe('should support parseName', () => {
it('getValues', function(done) {
const field = new Field(this, { parseName: true });
Expand Down
Loading

0 comments on commit 7fe0130

Please sign in to comment.