Skip to content

Commit

Permalink
feat(Form): add $processer to process the every $state
Browse files Browse the repository at this point in the history
  • Loading branch information
qiqiboy committed Mar 7, 2019
1 parent 3da6f90 commit 71a6200
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 49 deletions.
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Happy to build the forms in React ^\_^
+ [`$defaultValues`](#defaultvalues)
+ [`$defaultStates`](#defaultstates)
+ [`$onFormChange`](#onformchange)
+ [`$processer`](#processer)
+ [`$formutil`](#formutil-1)
* [`$new()`](#new)
* [`$getField(name)`](#getfieldname)
Expand Down Expand Up @@ -118,7 +119,7 @@ Happy to build the forms in React ^\_^

### 稳定版

稳定版支持所有`v15.0`以后版本的 react。稳定版文档请参考:[react-formutil稳定版](https://github.com/qiqiboy/react-formutil/tree/0.4.7)
稳定版支持所有`v15.0`以后版本的 react。稳定版文档请参考:[react-formutil 稳定版](https://github.com/qiqiboy/react-formutil/tree/0.4.7)

```bash
# npm
Expand Down Expand Up @@ -983,6 +984,56 @@ function MyComponent({ current, onUpdate }) {
}
```
#### `$processer`
> **注**:该属性为`v0.5.0`新增!
`$processer` 可以用来对表单域项的`$state`做进一步的加工!**在这里对`$state`做的修改都将影响到最终的表单状态!所以请慎用!**
`Form`控制器提取每个表单项的状态模型,汇总到`$formutil`中时,会将每个域的状态模型以及其`name`值传递给`$processer`函数,该函数可以对$state 进行修改、加工!
但是,请注意,这里对`$state`的修改,不会影响到表单项的实际的状态模型!
```javascript
/**
* @param $state: object 该表单域项的状态模型对象,{ $value, $valid, $invalid, $dirty, ... }
* @param name: string 该表单域项的name,例如:'username'
*/
function $processer($state, name) {
// proceess $state
}
```
**Form 在收集表单域的值时,是从`$state.$value`中获取的;而且还会判断该值是否为`undefined`,如果其值不存在,或者是`undefined`,并且`$state.$dirty`也是`true`,则会忽略该值!!**。
如果你了解以上信息,可以通过`$processer`方法,来对表单域的值做进一步的加工或过滤!
例如,当某些值不想被收集到`$params`中时,可以通过`$processer`来将其删除!
```javascript
// 将某些字段的对象值转换为字符串
<Form $processer={($state, name) => {
// userInfo为一个对象值,我们将其转换为json字符串
if (name === 'userInfo') {
$state.$value = JSON.stringify($state.$value);
}
}}

// 过滤掉所有值为Null或者Undefined的字段
<Form $processer={($state) => {
if ($value === undefined || $value === null) {
// 删除该值
delete $state.$value;
}
}}

// 强制所有的值都收集。通过将所有的$dirty都设置为true,来强制收集所有的值!
// 这里只是举例,实际中都不需要这么做!
<Form $processer={($state) => {
$state.$dirty = true;
}}
```
#### `$formutil`
`$formutil` 前面我们提到了,它是`Form`组件基于其组件树下的所有`Field`的状态模型,经过收集整理后返回的关于整个表单的状态模型集合。另外它也包含了一组用于操作整个表单的方法。
Expand Down Expand Up @@ -1180,6 +1231,10 @@ if ($invalid) {
所有表单项的 值`$value` 集合。`$formutil.$params` 是以 `Field``name` 值经过路径解析后的对象,`$formutil.$weakParams` 是以 `Field``name` 字符串当 key 的对象。
> **请注意:** 只有表单项的`$dirty`状态为`false`,或者其值`$value`不是`undefined`时,其值才会被收集解析道`$params`或者`$weakParams`中!
>
> 如果你希望调整该行为,可以通过[`$processer`](#processer)来调整表单对值的收集逻辑。
```javascript
$params = {
username: 'qiqiboy',
Expand Down
4 changes: 4 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ export interface FormComponentProps<Fields = {}, Validators = {}, WeakFields = F
newValues: FormParams<Fields>,
preValues: FormParams<Fields>
) => void);
$processer?: <K extends keyof WeakFields>(
$state: FieldState<DetectAny<WeakFields[K], string, WeakFields[K]>, Validators>,
name: K,
) => void;
component?: React.ComponentType;
render?: (($formutil: $Formutil<Fields, Validators, WeakFields>) => React.ReactNode);
children?: (($formutil: $Formutil<Fields, Validators, WeakFields>) => React.ReactNode) | React.ReactNode;
Expand Down
80 changes: 46 additions & 34 deletions lib/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,81 +104,92 @@ var Form = (_temp2 = _class = function (_Component) {
value: function render() {
var _this2 = this;

var $processer = this.props.$processer;

var $stateArray = Object.keys(this.$$registers).map(function (path) {
return {
path: path,
$state: _this2.$$registers[path].$getState()
};
});

var $invalid = $stateArray.some(function (_ref2) {
var $state = _ref2.$state;
return $state.$invalid;
var $weakParams = utils.toObject($stateArray, function ($params, _ref2) {
var path = _ref2.path,
$state = _ref2.$state;

if ($processer) {
$processer($state, path);
}

if ('$value' in $state && ($state.$dirty || !utils.isUndefined($state.$value))) {
$params[path] = $state.$value;
}
});
var $dirty = $stateArray.some(function (_ref3) {

var $invalid = $stateArray.some(function (_ref3) {
var $state = _ref3.$state;
return $state.$dirty;
return $state.$invalid;
});
var $touched = $stateArray.some(function (_ref4) {
var $dirty = $stateArray.some(function (_ref4) {
var $state = _ref4.$state;
return $state.$touched;
return $state.$dirty;
});
var $focused = $stateArray.some(function (_ref5) {
var $touched = $stateArray.some(function (_ref5) {
var $state = _ref5.$state;
return $state.$focused;
return $state.$touched;
});
var $pending = $stateArray.some(function (_ref6) {
var $focused = $stateArray.some(function (_ref6) {
var $state = _ref6.$state;
return $state.$focused;
});
var $pending = $stateArray.some(function (_ref7) {
var $state = _ref7.$state;
return $state.$pending;
});

var $formutil = this.$formutil = {
$$registers: this.$$registers,
$$deepRegisters: this.$$deepRegisters,
$states: utils.toObject($stateArray, function ($states, _ref7) {
var path = _ref7.path,
$state = _ref7.$state;
return utils.parsePath($states, path, $state);
}),
$params: utils.toObject($stateArray, function ($params, _ref8) {
$states: utils.toObject($stateArray, function ($states, _ref8) {
var path = _ref8.path,
$state = _ref8.$state;
return (!utils.isUndefined($state.$value) || $state.$dirty) && utils.parsePath($params, path, $state.$value);
}, Object.assign({}, this.$$defaultValues)),
$errors: utils.toObject($stateArray, function ($errors, _ref9) {
return utils.parsePath($states, path, $state);
}),
$params: utils.toObject($stateArray, function ($params, _ref9) {
var path = _ref9.path,
$state = _ref9.$state;
return path in $weakParams && utils.parsePath($params, path, $weakParams[path]);
}, Object.assign({}, this.$$defaultValues)),
$errors: utils.toObject($stateArray, function ($errors, _ref10) {
var path = _ref10.path,
$state = _ref10.$state;

if ($state.$invalid) {
utils.parsePath($errors, path, $state.$error);
}
}),
$dirts: utils.toObject($stateArray, function ($dirts, _ref10) {
var path = _ref10.path,
$state = _ref10.$state;
return utils.parsePath($dirts, path, $state.$dirty);
}),
$touches: utils.toObject($stateArray, function ($touches, _ref11) {
$dirts: utils.toObject($stateArray, function ($dirts, _ref11) {
var path = _ref11.path,
$state = _ref11.$state;
return utils.parsePath($touches, path, $state.$touched);
return utils.parsePath($dirts, path, $state.$dirty);
}),
$focuses: utils.toObject($stateArray, function ($focuses, _ref12) {
$touches: utils.toObject($stateArray, function ($touches, _ref12) {
var path = _ref12.path,
$state = _ref12.$state;
return utils.parsePath($focuses, path, $state.$focused);
return utils.parsePath($touches, path, $state.$touched);
}),

$weakStates: utils.toObject($stateArray, function ($states, _ref13) {
$focuses: utils.toObject($stateArray, function ($focuses, _ref13) {
var path = _ref13.path,
$state = _ref13.$state;
return $states[path] = $state;
return utils.parsePath($focuses, path, $state.$focused);
}),
$weakParams: utils.toObject($stateArray, function ($params, _ref14) {

$weakStates: utils.toObject($stateArray, function ($states, _ref14) {
var path = _ref14.path,
$state = _ref14.$state;
return (!utils.isUndefined($state.$value) || $state.$dirty) && ($params[path] = $state.$value);
return $states[path] = $state;
}),
$weakParams: $weakParams,
$weakErrors: utils.toObject($stateArray, function ($errors, _ref15) {
var path = _ref15.path,
$state = _ref15.$state;
Expand Down Expand Up @@ -274,7 +285,8 @@ var Form = (_temp2 = _class = function (_Component) {

$defaultValues: PropTypes.object,
$defaultStates: PropTypes.object,
$onFormChange: PropTypes.func
$onFormChange: PropTypes.func,
$processer: PropTypes.func
}, _class.defaultProps = {
$defaultValues: {},
$defaultStates: {}
Expand Down
4 changes: 2 additions & 2 deletions lib/withForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ function withForm(WrappedComponent) {
component = _props.component,
formProps = _objectWithoutProperties(_props, ['component']);

['$defaultStates', '$defaultValues', '$onFormChange'].forEach(function (prop) {
['$defaultStates', '$defaultValues', '$onFormChange', '$processer'].forEach(function (prop) {
if (prop in others) {
if (prop !== '$onFormChange') {
if (prop === '$defaultStates' || prop === '$defaultValues') {
formProps[prop] = Object.assign({}, config[prop], others[prop]);
}
delete others[prop];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-formutil",
"version": "0.5.0-beta.9",
"version": "0.5.0-beta.10",
"description": "Happy to build the forms in React ^_^",
"main": "lib/index.js",
"directories": {
Expand Down
24 changes: 15 additions & 9 deletions src/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class Form extends Component {
},
$defaultValues: PropTypes.object,
$defaultStates: PropTypes.object,
$onFormChange: PropTypes.func
$onFormChange: PropTypes.func,
$processer: PropTypes.func
};

static defaultProps = {
Expand Down Expand Up @@ -287,11 +288,22 @@ class Form extends Component {
}

render() {
const { $processer } = this.props;
const $stateArray = Object.keys(this.$$registers).map(path => ({
path,
$state: this.$$registers[path].$getState()
}));

const $weakParams = utils.toObject($stateArray, ($params, { path, $state }) => {
if ($processer) {
$processer($state, path);
}

if ('$value' in $state && ($state.$dirty || !utils.isUndefined($state.$value))) {
$params[path] = $state.$value;
}
});

const $invalid = $stateArray.some(({ $state }) => $state.$invalid);
const $dirty = $stateArray.some(({ $state }) => $state.$dirty);
const $touched = $stateArray.some(({ $state }) => $state.$touched);
Expand All @@ -304,9 +316,7 @@ class Form extends Component {
$states: utils.toObject($stateArray, ($states, { path, $state }) => utils.parsePath($states, path, $state)),
$params: utils.toObject(
$stateArray,
($params, { path, $state }) =>
(!utils.isUndefined($state.$value) || $state.$dirty) &&
utils.parsePath($params, path, $state.$value),
($params, { path, $state }) => path in $weakParams && utils.parsePath($params, path, $weakParams[path]),
{
...this.$$defaultValues
}
Expand All @@ -327,11 +337,7 @@ class Form extends Component {
),

$weakStates: utils.toObject($stateArray, ($states, { path, $state }) => ($states[path] = $state)),
$weakParams: utils.toObject(
$stateArray,
($params, { path, $state }) =>
(!utils.isUndefined($state.$value) || $state.$dirty) && ($params[path] = $state.$value)
),
$weakParams,
$weakErrors: utils.toObject($stateArray, ($errors, { path, $state }) => {
if ($state.$invalid) {
$errors[path] = $state.$error;
Expand Down
4 changes: 2 additions & 2 deletions src/withForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ function withForm(WrappedComponent, config = {}) {
const { ...others } = this.props;
const { component, ...formProps } = this.props;

['$defaultStates', '$defaultValues', '$onFormChange'].forEach(prop => {
['$defaultStates', '$defaultValues', '$onFormChange', '$processer'].forEach(prop => {
if (prop in others) {
if (prop !== '$onFormChange') {
if (prop === '$defaultStates' || prop === '$defaultValues') {
formProps[prop] = { ...config[prop], ...others[prop] };
}
delete others[prop];
Expand Down

0 comments on commit 71a6200

Please sign in to comment.