From 71a6200d54e139c70562fb006848fbe0a04935ab Mon Sep 17 00:00:00 2001 From: qiqiboy Date: Thu, 7 Mar 2019 13:17:59 +0800 Subject: [PATCH] feat(Form): add $processer to process the every $state --- README.md | 57 ++++++++++++++++++++++++++++++++++- index.d.ts | 4 +++ lib/Form.js | 80 ++++++++++++++++++++++++++++--------------------- lib/withForm.js | 4 +-- package.json | 2 +- src/Form.js | 24 +++++++++------ src/withForm.js | 4 +-- 7 files changed, 126 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 0eec643..59c8e2f 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 @@ -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 +// 将某些字段的对象值转换为字符串 +
{ + // userInfo为一个对象值,我们将其转换为json字符串 + if (name === 'userInfo') { + $state.$value = JSON.stringify($state.$value); + } +}} + +// 过滤掉所有值为Null或者Undefined的字段 + { + if ($value === undefined || $value === null) { + // 删除该值 + delete $state.$value; + } +}} + +// 强制所有的值都收集。通过将所有的$dirty都设置为true,来强制收集所有的值! +// 这里只是举例,实际中都不需要这么做! + { + $state.$dirty = true; +}} +``` + #### `$formutil` `$formutil` 前面我们提到了,它是`Form`组件基于其组件树下的所有`Field`的状态模型,经过收集整理后返回的关于整个表单的状态模型集合。另外它也包含了一组用于操作整个表单的方法。 @@ -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', diff --git a/index.d.ts b/index.d.ts index d271301..7182f71 100644 --- a/index.d.ts +++ b/index.d.ts @@ -315,6 +315,10 @@ export interface FormComponentProps, preValues: FormParams ) => void); + $processer?: ( + $state: FieldState, Validators>, + name: K, + ) => void; component?: React.ComponentType; render?: (($formutil: $Formutil) => React.ReactNode); children?: (($formutil: $Formutil) => React.ReactNode) | React.ReactNode; diff --git a/lib/Form.js b/lib/Form.js index c702d35..2f3db1f 100644 --- a/lib/Form.js +++ b/lib/Form.js @@ -104,6 +104,8 @@ 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, @@ -111,74 +113,83 @@ var Form = (_temp2 = _class = function (_Component) { }; }); - 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; @@ -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: {} diff --git a/lib/withForm.js b/lib/withForm.js index 1427b66..9db7718 100644 --- a/lib/withForm.js +++ b/lib/withForm.js @@ -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]; diff --git a/package.json b/package.json index 96c21cc..e9fc803 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/Form.js b/src/Form.js index fa04bbe..cb3ed1a 100644 --- a/src/Form.js +++ b/src/Form.js @@ -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 = { @@ -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); @@ -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 } @@ -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; diff --git a/src/withForm.js b/src/withForm.js index 206246a..6934667 100644 --- a/src/withForm.js +++ b/src/withForm.js @@ -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];