From bd17660c5f54eab63864166c57d364a73ca3e8b7 Mon Sep 17 00:00:00 2001 From: joe-sky Date: Fri, 5 Jun 2020 19:58:49 +0800 Subject: [PATCH] feat: :sparkles: Add dynamic update rule for MobxFormData --- docs/mobxFormData/demo/Demo4/index.tsx | 26 ++++--- docs/mobxFormData/demo/Demo4/style.less | 4 -- docs/mobxFormData/demo/Demo6.tsx | 67 +++++++++++++++++++ docs/mobxFormData/examples.md | 2 + package.json | 2 + .../babel-plugin-nornj-in-jsx/src/index.js | 4 +- packages/nornj-react/mobx/base.native.js | 1 - packages/nornj-react/package.json | 6 +- .../src/extension/mobx/base.native.ts | 8 --- .../nornj-react/src/extension/mobx/base.ts | 4 +- .../src/extension/mobx/mobxFormData.tsx | 22 ++++-- yarn.lock | 46 ++++++++----- 12 files changed, 135 insertions(+), 57 deletions(-) create mode 100644 docs/mobxFormData/demo/Demo6.tsx delete mode 100644 packages/nornj-react/mobx/base.native.js delete mode 100644 packages/nornj-react/src/extension/mobx/base.native.ts diff --git a/docs/mobxFormData/demo/Demo4/index.tsx b/docs/mobxFormData/demo/Demo4/index.tsx index d89fc91b..7df608b1 100644 --- a/docs/mobxFormData/demo/Demo4/index.tsx +++ b/docs/mobxFormData/demo/Demo4/index.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { Form, Input, Button, Icon } from 'antd'; +import { Form, Input, Button } from 'antd'; +import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons'; import { useLocalStore, useObserver } from 'mobx-react-lite'; import './style.less'; -import nj from 'nornj'; const formItemLayout = { labelCol: { @@ -48,20 +48,18 @@ export default () => { - - - 1}> - formData.delete(fieldName)} - /> - - + + 1}> + formData.delete(fieldName)} + /> + @@ -80,7 +78,7 @@ export default () => { count++; }} style={{ width: '60%' }}> - Add field + Add field diff --git a/docs/mobxFormData/demo/Demo4/style.less b/docs/mobxFormData/demo/Demo4/style.less index f7534295..7f1c79ee 100644 --- a/docs/mobxFormData/demo/Demo4/style.less +++ b/docs/mobxFormData/demo/Demo4/style.less @@ -1,9 +1,5 @@ .dynamic-form { max-width: 600px; - - .ant-form-item { - margin-bottom: 10px; - } } .dynamic-delete-button { diff --git a/docs/mobxFormData/demo/Demo6.tsx b/docs/mobxFormData/demo/Demo6.tsx new file mode 100644 index 00000000..603864eb --- /dev/null +++ b/docs/mobxFormData/demo/Demo6.tsx @@ -0,0 +1,67 @@ +import React, { useEffect } from 'react'; +import { Form, Input, Button, Checkbox } from 'antd'; +import { useLocalStore } from 'mobx-react-lite'; +import { observer } from 'mobx-react'; +import { reaction, autorun } from 'mobx'; + +const layout = { + labelCol: { span: 8 }, + wrapperCol: { span: 16 } +}; +const tailLayout = { + wrapperCol: { offset: 8, span: 16 } +}; + +const Demo = props => { + const state = useLocalStore(() => ({ + rememberMe: false + })); + + const { formData } = useLocalStore(() => ( + + + + + )); + + const onSubmit = (e: React.MouseEvent) => + formData + .validate() + .then(values => { + console.log(values); + }) + .catch(errorInfo => { + console.log(errorInfo); + }); + + const onRememberMeChange = () => { + formData.fieldDatas.get('password').rules[0].required = state.rememberMe; + formData.validate('password'); + }; + + return ( +
+ + + + + + + + + + + Remember me + + + + + + +
+ ); +}; + +export default observer(Demo); diff --git a/docs/mobxFormData/examples.md b/docs/mobxFormData/examples.md index 63e0ab82..07e00842 100644 --- a/docs/mobxFormData/examples.md +++ b/docs/mobxFormData/examples.md @@ -38,3 +38,5 @@ toc: menu 通过`validateMessages`自定义校验信息模板,模板内容可参考[此处](https://github.com/yiminghe/async-validator)。 + + diff --git a/package.json b/package.json index 8385ff8c..c139f1c9 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,8 @@ "@types/jest": "^24.0.22", "@types/jsdom": "^12.2.4", "@types/lodash": "^4.14.148", + "@types/react": "^16.9.35", + "@types/react-dom": "^16.9.8", "@typescript-eslint/eslint-plugin": "^2.5.0", "@typescript-eslint/parser": "^2.5.0", "babel-jest": "^26.0.1", diff --git a/packages/babel-plugin-nornj-in-jsx/src/index.js b/packages/babel-plugin-nornj-in-jsx/src/index.js index b46e2409..18a88cbf 100644 --- a/packages/babel-plugin-nornj-in-jsx/src/index.js +++ b/packages/babel-plugin-nornj-in-jsx/src/index.js @@ -169,9 +169,7 @@ module.exports = function(babel) { } if (state.hasMobxWithNj && !state.hasImportNjrMobx) { - path.node.body.unshift( - types.importDeclaration([], types.stringLiteral(`nornj-react/mobx${state.opts.rn ? '/native' : ''}`)) - ); + path.node.body.unshift(types.importDeclaration([], types.stringLiteral('nornj-react/mobx'))); } if (state.hasMobxFormDataWithNj && !state.hasImportNjrMobxFormData) { path.node.body.unshift(types.importDeclaration([], types.stringLiteral('nornj-react/mobx/formData'))); diff --git a/packages/nornj-react/mobx/base.native.js b/packages/nornj-react/mobx/base.native.js deleted file mode 100644 index 37fed5a0..00000000 --- a/packages/nornj-react/mobx/base.native.js +++ /dev/null @@ -1 +0,0 @@ -import '../lib/extension/mobx/base.native'; diff --git a/packages/nornj-react/package.json b/packages/nornj-react/package.json index b5a855fd..3fa7bfcc 100644 --- a/packages/nornj-react/package.json +++ b/packages/nornj-react/package.json @@ -34,7 +34,7 @@ "umd:router": "cross-env NODE_ENV=development WITH_EX=Router rollup -c -o dist/nornj-react-router.js", "min:router": "cross-env NODE_ENV=production WITH_EX=Router rollup -c -o dist/nornj-react-router.min.js", "lib": "babel src --out-dir lib --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", - "lib:mobx": "babel mobx/base.js --out-file mobx/index.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\" && babel mobx/base.native.js --out-file mobx/native.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", + "lib:mobx": "babel mobx/base.js --out-file mobx/index.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", "lib:mobxFormData": "babel mobx/formData/base.js --out-file mobx/formData/index.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", "lib:redux": "babel redux/base.js --out-file redux/index.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", "lib:router": "babel router/base.js --out-file router/index.js --extensions \".js,.jsx,.ts,.tsx\" --config-file \"../../.babelrc\"", @@ -69,8 +69,8 @@ "babel-plugin-module-resolver": "^3.2.0", "babel-plugin-nornj-in-jsx": "^5.2.0-rc.3", "echarts-for-react": "^2.0.15-beta.0", - "mobx": "^5.9.0", - "mobx-react": "^5.4.3", + "mobx": "^5.15.4", + "mobx-react": "^6.2.2", "mobx-react-lite": "^1.2.0", "nornj": "^5.2.0-rc.3", "react-redux": "^7.1.3", diff --git a/packages/nornj-react/src/extension/mobx/base.native.ts b/packages/nornj-react/src/extension/mobx/base.native.ts deleted file mode 100644 index 16d90c7e..00000000 --- a/packages/nornj-react/src/extension/mobx/base.native.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { registerComponent, registerFilter } from 'nornj'; -import { toJS } from 'mobx'; -import { Provider } from 'mobx-react/native'; -import './mobxBind'; -import './mobxObserver'; - -registerComponent('mobx-Provider', Provider); -registerFilter('toJS', v => toJS(v)); diff --git a/packages/nornj-react/src/extension/mobx/base.ts b/packages/nornj-react/src/extension/mobx/base.ts index 3b498f64..a3b91186 100644 --- a/packages/nornj-react/src/extension/mobx/base.ts +++ b/packages/nornj-react/src/extension/mobx/base.ts @@ -1,8 +1,6 @@ -import { registerComponent, registerFilter } from 'nornj'; +import { registerFilter } from 'nornj'; import { toJS } from 'mobx'; -import { Provider } from 'mobx-react'; import './mobxBind'; import './mobxObserver'; -registerComponent('mobx-Provider', Provider); registerFilter('toJS', v => toJS(v)); diff --git a/packages/nornj-react/src/extension/mobx/mobxFormData.tsx b/packages/nornj-react/src/extension/mobx/mobxFormData.tsx index 724b8849..28f1588d 100644 --- a/packages/nornj-react/src/extension/mobx/mobxFormData.tsx +++ b/packages/nornj-react/src/extension/mobx/mobxFormData.tsx @@ -1,5 +1,5 @@ import nj, { registerExtension } from 'nornj'; -import { observable, runInAction, reaction, extendObservable, isComputedProp } from 'mobx'; +import { observable, runInAction, reaction, extendObservable, isComputedProp, observe } from 'mobx'; import schema, { RuleItem } from 'async-validator'; import extensionConfigs from '../../../mobx/formData/extensionConfig'; import { MobxFormDataProps, MobxFormDataInstance, MobxFieldDataProps, MobxFieldDataInstance } from '../../interface'; @@ -104,7 +104,15 @@ const createFormData = ( const { name, value, trigger = 'valueChange', rules, ...ruleOptions } = fieldData; const fd: MobxFieldDataInstance = { name, value, trigger, rules, ...ruleOptions }; const _rules = rules ? rules : [ruleOptions]; - fd.rules = _rules; + fd.rules = _rules.map((rule, i) => { + const oRule = observable(rule); + observe(oRule, change => { + const schemaRules: RuleItem[] = (fd.validatorSchema as any).rules[name]; + Object.assign(schemaRules[i], oRule); + }); + + return oRule; + }); fd.setDefaultRule = rule => { const schemaRules: RuleItem[] = (fd.validatorSchema as any).rules[name]; @@ -140,9 +148,10 @@ const createFormData = ( }); fd.reset = function() { - this._resetting = true; + if (this.value !== value) { + this._resetting = true; + } this.value = value; - this._resetting = false; }; const oFd = observable(fd); @@ -177,6 +186,7 @@ const createFormData = ( if (!oFd._resetting) { this.validate(name).catch(nj.noop); } + oFd._resetting = false; } ); } @@ -242,7 +252,9 @@ registerExtension( tagProps.validateStatus = oFd.validateStatus; tagProps.help = oFd.help; - tagProps.required = oFd.rules.find(rule => rule.required); + if (tagProps.required == null) { + tagProps.required = oFd.rules.find(rule => rule.required); + } if (tagProps.label) { oFd.label = tagProps.label; } else if (oFd.label) { diff --git a/yarn.lock b/yarn.lock index 53ec8699..72c051cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3892,6 +3892,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^16.9.8": + version "16.9.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" + integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA== + dependencies: + "@types/react" "*" + "@types/react-native@^0.60.22": version "0.60.22" resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.60.22.tgz#ba199a441cb0612514244ffb1d0fe6f04c878575" @@ -3969,6 +3976,14 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/react@^16.9.35": + version "16.9.35" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.35.tgz#a0830d172e8aadd9bd41709ba2281a3124bbd368" + integrity sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -10055,7 +10070,7 @@ hoek@2.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz#b09178f0122184fb95acf525daaecb4d8f45958b" integrity sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA== @@ -13013,23 +13028,27 @@ mkdirp@^0.5.3, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" +mobx-react-lite@2: + version "2.0.7" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284" + integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q== + mobx-react-lite@^1.2.0: version "1.5.0" resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-1.5.0.tgz#a5867fa1114b19056cf8159e8d64766596ae85a0" integrity sha512-Ss8RLKKGn+QhKbfCHvQ4+RPEVKR8AnPW1wNyWzZAS3wYw7UP4FX6GdRn64sdOhrP646o/JtXbLuDuc4RH3Bqyg== -mobx-react@^5.4.3: - version "5.4.4" - resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-5.4.4.tgz#b3de9c6eabcd0ed8a40036888cb0221ab9568b80" - integrity sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ== +mobx-react@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.2.tgz#45e8e7c4894cac8399bba0a91060d7cfb8ea084b" + integrity sha512-Us6V4ng/iKIRJ8pWxdbdysC6bnS53ZKLKlVGBqzHx6J+gYPYbOotWvhHZnzh/W5mhpYXxlXif4kL2cxoWJOplQ== dependencies: - hoist-non-react-statics "^3.0.0" - react-lifecycles-compat "^3.0.2" + mobx-react-lite "2" -mobx@^5.9.0: - version "5.14.2" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.14.2.tgz#608b8ee9bc9f9e406b48da676e677b150e901eba" - integrity sha512-yx5Xe6o2WSYFgeytzZt6jGaYghJdQbd1ElR7S2s93x7/+5SYfJBfutvZF1O5gPEsUyTAFZ5IMYGu1KyhkPk+oQ== +mobx@^5.15.4: + version "5.15.4" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" + integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== mocha@^3.0.2: version "3.5.3" @@ -15722,11 +15741,6 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa" integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw== -react-lifecycles-compat@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - react-redux@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.3.tgz#717a3d7bbe3a1b2d535c94885ce04cdc5a33fc79"