1.轴心createBaseForm.js模块:封装WrappedComponent下游组件,为其提供props.form表单赋值、校验工具函数集。
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); // defineProperty(obj,name,value)定义对象的属性 var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); // 拷贝 var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _utils = require('./utils'); var _asyncValidator = require('async-validator'); var _asyncValidator2 = _interopRequireDefault(_asyncValidator); var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); var _lodash = require('lodash.get'); var _lodash2 = _interopRequireDefault(_lodash); var _lodash3 = require('lodash.has'); var _lodash4 = _interopRequireDefault(_lodash3); var _lodash5 = require('lodash.set'); var _lodash6 = _interopRequireDefault(_lodash5); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var DEFAULT_VALIDATE_TRIGGER = 'onChange'; var DEFAULT_TRIGGER = DEFAULT_VALIDATE_TRIGGER; var atom = {}; // createBaseForm({ // mapPropsToFields,// 页面初始化或重绘时,将组件接受到的props转变为表单项数据注入this.fields中 // onFieldsChange,// 表单项发生改变时执行函数,可以将表单项的值存入redux.store // fieldNameProp,// 设置表单项存储name的键 // fieldMetaProp,// 用于getFieldProps添加的数据转化后挂载到元素的props,提供键 // validateMessages,// 设置表单的错误文案 // mapProps,// render方法渲染时对组件的props进行处理 // formPropName,// 被包装组件获取getFieldProps方法的接口名,默认为this.props.form // withRef,// 设定被封装组件的ref属性为"wrappedComponent" // },mixins) function createBaseForm() { var option = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var mixins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var mapPropsToFields = option.mapPropsToFields,// 页面初始化或重绘时,将组件接受到的props转变为表单项数据注入this.fields中 onFieldsChange = option.onFieldsChange,// 表单项发生改变时执行函数,可以将表单项的值存入redux.store fieldNameProp = option.fieldNameProp,// 设置表单项存储name的键 fieldMetaProp = option.fieldMetaProp,// 用于getFieldProps添加的数据转化后挂载到元素的props,提供键 validateMessages = option.validateMessages,// 设置表单的错误文案 _option$mapProps = option.mapProps,// render方法渲染时对被封装组件的props进行处理 mapProps = _option$mapProps === undefined ? _utils.mirror : _option$mapProps, _option$formPropName = option.formPropName,// 被包装组件获取getFieldProps方法的接口名,默认为this.props.form formPropName = _option$formPropName === undefined ? 'form' : _option$formPropName, withRef = option.withRef;// 设定被封装组件的ref属性为"wrappedComponent" // 封装高阶组件,为下游WrappedComponent组件注入this.props.form工具函数集等 function decorate(WrappedComponent) { var Form = _react2["default"].createClass({ displayName: 'Form', mixins: mixins, getInitialState: function getInitialState() { var fields = void 0; if (mapPropsToFields) { fields = mapPropsToFields(this.props); } this.fields = fields || {};// 存储表单项的值,错误文案等即时数据,重绘表单时props从this.fields取值 this.instances = {}; this.fieldsMeta = {};// 存储getFieldProps、getFieldDecorator方法经过数据处理后的原始配置值,{name:options}形式 this.cachedBind = {};// 存储绑点事件相关onChange、onChangeValidate、以及删除数据相关this.saveRef方法 return { submitting: false }; }, // 表单重绘时,通过mapPropsToFields从props中获取数据注入this.fields componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (mapPropsToFields) { this.fields = mapPropsToFields(nextProps); } }, // change事件发生时,获取表单项的改变值,有校验规则的表单项添加{dirty:true}属性,调用setFields方法重绘表单 onChange: function onChange(name_, action) { var name = name_; var fieldMeta = this.getFieldMeta(name); var validate = fieldMeta.validate; // react注入的事件参数,如event等 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } // 调用getFieldProps(name,{onChange:functaion(){}})方式添加的onChange方法 if (fieldMeta[action]) { fieldMeta[action].apply(fieldMeta, args); // 调用getFieldDecorator(name,fieldOption)(<Input onChange={function(){}}/>)添加的onChange方法 // fieldMeta.originalProps属性在调用getFieldDecorator方法封装表单项时会产生 } else if (fieldMeta.originalProps && fieldMeta.originalProps[action]) { var _fieldMeta$originalPr; (_fieldMeta$originalPr = fieldMeta.originalProps)[action].apply(_fieldMeta$originalPr, args); } // _utils.getValueFromEvent(e)获取表单项的即时值,即e.target.value | checked var value = fieldMeta.getValueFromEvent ? fieldMeta.getValueFromEvent.apply(fieldMeta, args) : _utils.getValueFromEvent.apply(undefined, args); var fieldContent = void 0; var nameKeyObj = (0, _utils.getNameIfNested)(name); if (this.getFieldMeta(nameKeyObj.name).exclusive) { name = nameKeyObj.name; } var field = this.getField(name); fieldContent = (0, _extends3["default"])({}, field, { value: value, dirty: (0, _utils.hasRules)(validate)// 有校验规则时dirty属性赋值为true }); // this.fields重新赋值,并调用this.forceUpdate重绘页面 this.setFields((0, _defineProperty3["default"])({}, name, fieldContent)); }, // change事件发生时,获取表单项的改变值,表单项添加{dirty:true}属性,调用validateFieldsInternal方法校验该表单项 onChangeValidate: function onChangeValidate(name_, action) { var name = name_; var fieldMeta = this.getFieldMeta(name); // react注入的事件参数,如event等 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { args[_key2 - 2] = arguments[_key2]; } // 调用getFieldProps(name,{onChange:functaion(){}})方式添加的onChange方法 if (fieldMeta[action]) { fieldMeta[action].apply(fieldMeta, args); // 调用getFieldDecorator(name,fieldOption)(<Input onChange={function(){}}/>)添加的onChange方法 // fieldMeta.originalProps属性在调用getFieldDecorator方法封装表单项时会产生 } else if (fieldMeta.originalProps && fieldMeta.originalProps[action]) { var _fieldMeta$originalPr2; (_fieldMeta$originalPr2 = fieldMeta.originalProps)[action].apply(_fieldMeta$originalPr2, args); } // _utils.getValueFromEvent(e)获取表单项的即时值,即e.target.value | checked var value = fieldMeta.getValueFromEvent ? fieldMeta.getValueFromEvent.apply(fieldMeta, args) : _utils.getValueFromEvent.apply(undefined, args); var nameKeyObj = (0, _utils.getNameIfNested)(name); if (this.getFieldMeta(nameKeyObj.name).exclusive) { name = nameKeyObj.name; } var field = this.getField(name); field.value = value; field.dirty = true; this.validateFieldsInternal([field], { action: action, options: { firstFields: !!fieldMeta.validateFirst } }); }, // 缓存或获取cache中缓存的校验数据方法onChangeValidate、收集表单项数据的方法onChange、移除数据的方法saveRef getCacheBind: function getCacheBind(name, action, fn) { var cache = this.cachedBind[name] = this.cachedBind[name] || {}; if (!cache[action]) { cache[action] = fn.bind(this, name, action); } return cache[action]; }, // 获取getFieldProps(name,fieldOption)、getFieldDecorator(name,fieldOption)注入的表单项元数据fieldOption // fieldOption经数据处理后 getFieldMeta: function getFieldMeta(name) { return this.fieldsMeta[name]; }, // 获取this.fields[name],并添加{name:name}属性后输出 getField: function getField(name) { var fields = this.fields; return (0, _extends3["default"])({}, fields[name], { name: name }); }, // {getFieldDecorator(name,fieldOption)(<Input {...props}/>)}将表单项包装为高阶组件后返回 // 实现功能同getFieldProps方法,内部也调用getFieldProps方法 // 与getFieldProps方法不同的是,被封装表单项的props作为this.fieldMeta[name]的originalProps属性 // originalProps属性的主要目的存储被封装表单项的onChange事件,fieldOption下无同类事件时,执行该事件 // 不推荐将value、defaultValue作为表单项组件如Input的props属性 getFieldDecorator: function getFieldDecorator(name, fieldOption) { var _this = this; var props = this.getFieldProps(name, fieldOption); return function (fieldElem) { var fieldMeta = _this.getFieldMeta(name); var originalProps = fieldElem.props; if (process.env.NODE_ENV !== 'production') { var valuePropName = fieldMeta.valuePropName; (0, _warning2["default"])(!(valuePropName in originalProps), '`getFieldDecorator` will override `' + valuePropName + '`, ' + ('so please don\'t set `' + valuePropName + '` directly ') + 'and use `setFieldsValue` to set it.'); var defaultValuePropName = 'default' + valuePropName[0].toUpperCase() + valuePropName.slice(1); (0, _warning2["default"])(!(defaultValuePropName in originalProps), '`' + defaultValuePropName + '` is invalid ' + ('for `getFieldDecorator` will set `' + valuePropName + '`,') + ' please use `option.initialValue` instead.'); } fieldMeta.originalProps = originalProps; fieldMeta.ref = fieldElem.ref; return _react2["default"].cloneElement(fieldElem, (0, _extends3["default"])({}, props, _this.getFieldValuePropValue(fieldMeta))); }; }, /* getFieldProps(name,{// 待校验节点的唯一标志。支持嵌套式的写法,单层嵌套,不稳定,后续版本中有所调整 valuePropName,// 待校验节点的值设置,如Switch的是'checked' validate,// 校验规则,数据格式为{trigger:"",rules:[{}]} rules,// 校验规则rules:[{required:true,message:"name is required."}] validate,// 校验时机及校验规则validate:[trigger:"onClick",rules:[{required:true,message:"name is required."}]] trigger,// 收集待校验节点的值的时机,默认"onChange" validateTrigger,// 校验待校验节点的值的时机,默认"onChange" initialValue,// 待校验节点的初始值,类型、可选值均由待校验节点决定 exclusive,// 设为真值时,获取表单项数据和校验时将排除在外,譬如用于控制input元素显隐的radio、checkbox等;同时name要求是嵌套结构 initialValue,// 表单项的初始值 valuePropName,// 定义存储数据的键,同时作为react元素表单项的属性名,用于存储initialValue等,默认为value getValueProps(fieldValue),// 传入表单项的值,定义表单项存储该值得属性名后,以对象形式输出 getValueFromEvent(e),// onChange事件触发时,定义以何种形式获取表单项的即时值,默认为e.target.value || checked normalize:function(value,prevValues,nextValues){},// this.setFields方法中用于格式化表单项的值 onChange:function(){},// 设置表单项值改变时的事件,该数据不会流入inputProps,作为表单项的props属性;但会在this.onChange方法中得到调用 ref:function(component){},// 设置组件实例ref属性将执行的回调函数,component为该组件实例 }) <Input {...getFieldProps(name,fieldOption)}/> */ // 将转化后的数据存入this.fieldsMeta中,校验数据以validateRules=[{trigger,rules}]的形式 // 不包含inputProps中的inputProps[action]、inputProps[fieldOption.trigger],添加到react元素上的绑定事件 // 添加到元素上的props为getFieldProps(name,{trigger,rules})函数体内的inputProps // 包含校验触发方法{[action]:this.onChangeValidate}、收集数据的方法{[trigger]:this.onChange} // 通过this.getFieldValuePropValue获取的元素的值{value:initialValue} // 用于移除this.fields|fieldsMeta|instances|cachedBind[name]相关数据的方法{ref:this.saveRef} // 以及作为元素属性存储的getFieldProps方法次参配置项(经转化后){[options.fieldMetaProp]:meta} // options.fieldMetaProp为ant-design中使用Form.create({fieldMetaProp})传参 // 调用this.forceUpdate重绘表单时,将调用getFieldProps通过this.fields重新计算表单项的props getFieldProps: function getFieldProps(name) { var _this2 = this; var fieldOption = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!name) { throw new Error('Must call `getFieldProps` with valid name string!'); } // fieldOption数据转化 fieldOption.valuePropName = fieldOption.valuePropName || 'value'; fieldOption.validate = fieldOption.validate || []; var rules = fieldOption.rules, _fieldOption$trigger = fieldOption.trigger, trigger = _fieldOption$trigger === undefined ? DEFAULT_TRIGGER : _fieldOption$trigger, exclusive = fieldOption.exclusive, _fieldOption$validate = fieldOption.validateTrigger, validateTrigger = _fieldOption$validate === undefined ? DEFAULT_VALIDATE_TRIGGER : _fieldOption$validate, validate = fieldOption.validate; fieldOption.trigger = trigger; fieldOption.validateTrigger = validateTrigger; // name设置为"key1.key2"形式或"key1[key2]"形式,取得nameIfNested为{name:"key1",isNested:true} // name不是嵌套形式如"key",返回{name:"key"} // 示例: // 设置嵌套结构为: // {getFieldDecorator('member[0].name.firstname', {})(<input/>)} // {getFieldDecorator('member[1].name.firstname', {})(<input/>)} // getFieldsValue方法返回数据为:members: [{ name: {firstname: "xxx"} }, { name: {firstname: "yyy"} }] var nameIfNested = (0, _utils.getNameIfNested)(name); var leadingName = nameIfNested.name;// name为嵌套结构如"key1.key2"的父键"key1" fieldOption.leadingName = leadingName; fieldOption.name = name; var fieldsMeta = this.fieldsMeta; var fieldMeta = void 0; var leadingFieldMeta = fieldsMeta[leadingName]; if (nameIfNested.isNested) { leadingFieldMeta = fieldsMeta[leadingName] = fieldsMeta[leadingName] || {}; leadingFieldMeta.virtual = !exclusive; // exclusive allow getFieldProps('x', {initialValue}) // non-exclusive does not allow getFieldProps('x', {initialValue}) leadingFieldMeta.hidden = !exclusive; leadingFieldMeta.exclusive = exclusive; fieldMeta = fieldsMeta[name] = fieldsMeta[name] || {}; } else { fieldMeta = fieldsMeta[name] = fieldsMeta[name] || {}; } if ('initialValue' in fieldOption) { fieldMeta.initialValue = fieldOption.initialValue; } var inputProps = {}; if (fieldNameProp) { inputProps[fieldNameProp] = name; } // 将fieldOption.validate、fieldOption.rules并入validateRules中 var validateRules = validate.map(function (item) { var newItem = (0, _extends3["default"])({}, item, { trigger: item.trigger || [] }); if (typeof newItem.trigger === 'string') { newItem.trigger = [newItem.trigger]; } return newItem; }); if (rules) { validateRules.push({ trigger: validateTrigger ? [].concat(validateTrigger) : [], rules: rules }); } // 将_this2.onChangeValidate.bind(this,name,action);函数存入this.cachedBind[name][action] // inputProps存储{action:this.cachedBind[name][action]} // 其中action如"onChange",name为待校验节点的唯一标识 // this.onChangeValidate方法用于校验节点 validateRules.filter(function (item) { return !!item.rules && item.rules.length; }).map(function (item) { return item.trigger; }).reduce(function (pre, curr) { return pre.concat(curr); }, []).forEach(function (action) { // 将_this2.onChangeValidate.bind(this,name,action)函数存入this.cachedBind[name][action] inputProps[action] = _this2.getCacheBind(name, action, _this2.onChangeValidate); }); function checkRule(item) { return item.trigger.indexOf(trigger) === -1 || !item.rules || !item.rules.length; } // 校验validateRules数组各元素项的trigger是否不包含fieldOption.trigger及rules是否存在 // 通过校验,将this.onChange.bind(this,name,trigger)存入this.cachedBind[name][trigger] // inputProps存储{trigger:this.cachedBind[name][trigger]} // this.onChange方法用于收集数据 if (trigger && validateRules.every(checkRule)) { inputProps[trigger] = this.getCacheBind(name, trigger, this.onChange); } // getFieldValuePropValue方法以键值对形式获取this.fields[name].value表单项的实时值 // 或fieldOption.initialValue初始值 // 键为fieldOption.valuePropName,默认为"value",最终作为表单项的props属性 inputProps = (0, _extends3["default"])({}, inputProps, this.getFieldValuePropValue(fieldOption)); // 将this.saveRef.bind(this,name,name+'__ref')存入this.cachedBind[name][name+'__ref'] // 存储的函数用于移除this.fields | fieldsMeta | instances | cachedBind中存储的相关数据 inputProps.ref = this.getCacheBind(name, name + '__ref', this.saveRef); var meta = (0, _extends3["default"])({}, fieldMeta, fieldOption, { validate: validateRules }); // 将转化后的数据存入this.fieldsMeta中,校验数据以validateRules=[{trigger,rules}]的形式 // 不包含inputProps中的inputProps[action]、inputProps[trigger],添加到react元素上的绑定事件 fieldsMeta[name] = meta; // ant-design中使用Form.create({fieldMetaProp}),fieldMetaProp作为将getFieldProps添加的数据处理后挂载的键 if (fieldMetaProp) { inputProps[fieldMetaProp] = meta; } return inputProps; }, // 传参fieldMeta为getFieldProps(name,fieldOption)方法中经数据处理后的fieldOption // 以键值对形式获取this.fields[name].value表单项的实时值或fieldOption.initialValue初始值 // 键为fieldOption.valuePropName,默认为"value",最终作为表单项的props属性 getFieldValuePropValue: function getFieldValuePropValue(fieldMeta) { var exclusive = fieldMeta.exclusive, leadingName = fieldMeta.leadingName, name = fieldMeta.name, getValueProps = fieldMeta.getValueProps, valuePropName = fieldMeta.valuePropName; var fieldsMeta = this.fieldsMeta; // 获取this.fields[name],形式为{name:name} var field = exclusive ? this.getField(leadingName) : this.getField(name); var fieldValue = atom; // 预先获取调用this.setFields方法强制向this.fields[name]表单项注入的值 if (field && 'value' in field) { fieldValue = field.value; } // 其次获取getFieldProps(name,{initialValue})方法添加的初始值 if (fieldValue === atom) { fieldValue = exclusive ? fieldsMeta[leadingName].initialValue : fieldMeta.initialValue; } // 由表单项的值转化为键值对输出 if (getValueProps) { return getValueProps(fieldValue); } // 转化为键值对{[fieldOption.valuePropName]:fieldValue}形式后输出 return (0, _defineProperty3["default"])({}, valuePropName, fieldValue); }, // 获取this.fields[name][member]属性数据 getFieldMember: function getFieldMember(name, member) { var field = this.getField(name); return field && field[member]; }, // 获取this.fields[name]["errors"]错误数据,并剔除没有error.message的错误数据 getFieldError: function getFieldError(name) { return (0, _utils.getErrorStrs)(this.getFieldMember(name, 'errors')); }, // 获取所有表单项的name,getFieldProps(name,{exclusive:true})中exclusive设为真值的除外 getValidFieldsName: function getValidFieldsName() { var fieldsMeta = this.fieldsMeta; return fieldsMeta ? Object.keys(fieldsMeta).filter(function (name) { return !fieldsMeta[name].hidden; }) : []; }, // 遍历names以获得表单项的name,为空时获取this.fieldsMeta下的所有表单项name // 接着获取表单项的值this.fields[name].value或者this.fieldsMeta[name].initialValue // 特别当name为嵌套结构的父键如"pKey"时,获取该父键下所有子嵌套表单项如pKey.childKey1、pKey.childKey2的值 getFieldsValue: function getFieldsValue(names) { var _this3 = this; // utils.flatFieldNames方法,name若为非嵌套式书写"key",获取"key";若为嵌套式书写"key1.key2",获取父键"key1" var fields = names || (0, _utils.flatFieldNames)(this.getValidFieldsName()); var allValues = {}; fields.forEach(function (f) { (0, _lodash6["default"])(allValues, f, _this3.getFieldValue(f)); }); return allValues; }, // 获取表单项的值this.fields[name].value或者this.fieldsMeta[name].initialValue // 特别当name为嵌套结构的父键如"pKey"时,获取该父键下所有子嵌套表单项如pKey.childKey1、pKey.childKey2的值 getFieldValue: function getFieldValue(name) { var fields = this.fields; return this.getValueFromFields(name, fields); }, // 获取表单项组件实例,该实例何时添加到this.instances中??? getFieldInstance: function getFieldInstance(name) { return this.instances[name]; }, // 获取表单项的值this.fields[name].value或者this.fieldsMeta[name].initialValue getValueFromFieldsInternal: function getValueFromFieldsInternal(name, fields) { var field = fields[name]; if (field && 'value' in field) { return field.value; } var fieldMeta = this.fieldsMeta[name]; return fieldMeta && fieldMeta.initialValue; }, // 获取表单项的值this.fields[name].value或者this.fieldsMeta[name].initialValue // 特别当name为嵌套结构的父键如"pKey"时,获取该父键下所有子嵌套表单项如pKey.childKey1、pKey.childKey2的值 getValueFromFields: function getValueFromFields(name, fields) { var fieldsMeta = this.fieldsMeta; // fieldsMeta[name].virtual仅当getFieldProps(name,{exclusive:true})中exclusive为真时,为否值;其余都是真值 // 当name为嵌套结构的父键时,获取该父键下所有子嵌套表单项的值 if (fieldsMeta[name] && fieldsMeta[name].virtual) { var ret = {}; for (var fieldKey in fieldsMeta) { if (fieldsMeta.hasOwnProperty(fieldKey)) { var nameIfNested = (0, _utils.getNameIfNested)(fieldKey); if (nameIfNested.name === name && nameIfNested.isNested) { (0, _lodash6["default"])(ret, fieldKey, this.getValueFromFieldsInternal(fieldKey, fields)); } } } return ret[name]; } return this.getValueFromFieldsInternal(name, fields); }, // 通过action事件名获取校验规则 getRules: function getRules(fieldMeta, action) { var actionRules = fieldMeta.validate.filter(function (item) { return !action || item.trigger.indexOf(action) >= 0; }).map(function (item) { return item.rules; }); return (0, _utils.flattenArray)(actionRules); }, // setFields(fields)方法重新计算表单项的value值,赋值给this.fields // 并调用用户配置onFieldsChange(props,values)方法,用于将表单数据存入redux.store // 最后调用this.forceUpdate重绘表单,重绘表单时必然调用getFieldProps通过this.fields重新计算表单项的props setFields: function setFields(fields_) { var _this4 = this; var fieldsMeta = this.fieldsMeta; var fields = fields_; var nowFields = (0, _extends3["default"])({}, this.fields, fields); // 以对象形式获取待赋值表单项及之前所有表单项的值,getFieldProps(name,{exclusive:true})中exclusive为真值的除外 var nowValues = {}; Object.keys(fieldsMeta).forEach(function (f) { var _getNameIfNested = (0, _utils.getNameIfNested)(f), name = _getNameIfNested.name, isNested = _getNameIfNested.isNested; if (isNested && fieldsMeta[name].exclusive) { return; } nowValues[f] = _this4.getValueFromFields(f, nowFields); }); var changedFieldsName = Object.keys(fields); // getFieldProps(name,{normalize:function(value,prevValues,nextValues){}})中normalize方法格式化表单项的值 Object.keys(nowValues).forEach(function (f) { var value = nowValues[f]; var fieldMeta = fieldsMeta[f]; if (fieldMeta && fieldMeta.normalize) { var nowValue = fieldMeta.normalize(value, _this4.getValueFromFields(f, _this4.fields), nowValues); if (nowValue !== value) { nowFields[f] = (0, _extends3["default"])({}, nowFields[f], { value: nowValue }); } } }); this.fields = nowFields; if (onFieldsChange) { (function () { var changedFields = {}; changedFieldsName.forEach(function (f) { changedFields[f] = _this4.getField(f); }); onFieldsChange(_this4.props, changedFields); })(); } this.forceUpdate(); }, // 通过键值对设置表单项的值,并调用setFields方法重绘表单页面 setFieldsValue: function setFieldsValue(fieldsValue) { var newFields = {}; var fieldsMeta = this.fieldsMeta, fields = this.fields; // utils.getVirtualPaths(fieldsMeta)方法 // getFieldProps(name,fieldOption)中,name若以嵌套形式设置为"pKey.cKey" // 将获得virtualPaths为{pKey:"pKey.cKey"} // 所有name均为非嵌套形式"key",将获得virtualPaths为{} var virtualPaths = (0, _utils.getVirtualPaths)(fieldsMeta); for (var name in fieldsValue) { if (fieldsValue.hasOwnProperty(name)) { var value = fieldsValue[name]; // getFieldProps(name,{exclusive:false})中name设定为嵌套形式,且exclusive为否值(默认为否值)时 // fieldsMeta[name].virtual为真值 // name为嵌套形式的父键,获取该键下所有嵌套属性对应表单项的值 if (fieldsMeta[name] && fieldsMeta[name].virtual) { // utils.clearVirtualField用于删除fields中name不是嵌套结构的键 (0, _utils.clearVirtualField)(name, fields, fieldsMeta); for (var i = 0, len = virtualPaths[name].length; i < len; i++) { var path = virtualPaths[name][i]; if ((0, _lodash4["default"])(fieldsValue, path)) { newFields[path] = { name: path, value: (0, _lodash2["default"])(fieldsValue, path) }; } } // name非嵌套形式,获取表单项的值 } else if (fieldsMeta[name]) { newFields[name] = { name: name, value: value }; } } } this.setFields(newFields); }, // 通过键值对设置表单项的初始值initialValue,并调用setFields方法重绘表单页面 setFieldsInitialValue: function setFieldsInitialValue(initialValues) { var fieldsMeta = this.fieldsMeta; var virtualPaths = (0, _utils.getVirtualPaths)(fieldsMeta); for (var name in initialValues) { if (initialValues.hasOwnProperty(name)) { if (fieldsMeta[name] && fieldsMeta[name].virtual) { for (var i = 0, len = virtualPaths[name].length; i < len; i++) { var path = virtualPaths[name][i]; if ((0, _lodash4["default"])(initialValues, path)) { fieldsMeta[path] = (0, _extends3["default"])({}, fieldsMeta[path], { initialValue: (0, _lodash2["default"])(initialValues, path) }); } } } else if (fieldsMeta[name]) { fieldsMeta[name] = (0, _extends3["default"])({}, fieldsMeta[name], { initialValue: initialValues[name] }); } } } }, // 通过getCacheBind作为组件实例ref属性,回调函数形式,this.instances添加实例 saveRef: function saveRef(name, _, component) { if (!component) { // after destroy, delete data delete this.fieldsMeta[name]; delete this.fields[name]; delete this.instances[name]; delete this.cachedBind[name]; return; } var fieldMeta = this.getFieldMeta(name); if (fieldMeta) { var ref = fieldMeta.ref; if (ref) { if (typeof ref === 'string') { throw new Error('can not set ref string for ' + name); } ref(component); } } this.instances[name] = component; }, // 参数fields为数组形式待校验的表单项 // _ref2={fieldNames,action,options}校验配置,options又作为async-validate模块的执行配置 // options.force强制对表单项作校验,即便field.dirty为false,指示校验完成 // callback(errors,values)根据fields设置值完成及校验完成后执行的回调函数 // 调用setFields设置表单项的值并做校验,校验完成后执行setFields重绘校验文案,两次setFields方法后执行callback回调 validateFieldsInternal: function validateFieldsInternal(fields, _ref2, callback) { var _this5 = this; var fieldNames = _ref2.fieldNames, action = _ref2.action, _ref2$options = _ref2.options, options = _ref2$options === undefined ? {} : _ref2$options; var allRules = {}; var allValues = {}; var allFields = {}; var alreadyErrors = {}; fields.forEach(function (field) { var name = field.name; if (options.force !== true && field.dirty === false) { if (field.errors) { (0, _lodash6["default"])(alreadyErrors, name, { errors: field.errors }); } return; } var fieldMeta = _this5.getFieldMeta(name); var newField = (0, _extends3["default"])({}, field); newField.errors = undefined; newField.validating = true; newField.dirty = true; allRules[name] = _this5.getRules(fieldMeta, action); allValues[name] = newField.value; allFields[name] = newField; }); this.setFields(allFields); // in case normalize Object.keys(allValues).forEach(function (f) { allValues[f] = _this5.getFieldValue(f); }); if (callback && (0, _utils.isEmptyObject)(allFields)) { callback((0, _utils.isEmptyObject)(alreadyErrors) ? null : alreadyErrors, this.getFieldsValue((0, _utils.flatFieldNames)(fieldNames))); return; } var validator = new _asyncValidator2["default"](allRules); if (validateMessages) { validator.messages(validateMessages); } validator.validate(allValues, options, function (errors) { var errorsGroup = (0, _extends3["default"])({}, alreadyErrors); if (errors && errors.length) { errors.forEach(function (e) { var fieldName = e.field; if (!(0, _lodash4["default"])(errorsGroup, fieldName)) { (0, _lodash6["default"])(errorsGroup, fieldName, { errors: [] }); } var fieldErrors = (0, _lodash2["default"])(errorsGroup, fieldName.concat('.errors')); fieldErrors.push(e); }); } var expired = []; var nowAllFields = {}; Object.keys(allRules).forEach(function (name) { var fieldErrors = (0, _lodash2["default"])(errorsGroup, name); var nowField = _this5.getField(name); // avoid concurrency problems if (nowField.value !== allValues[name]) { expired.push({ name: name }); } else { nowField.errors = fieldErrors && fieldErrors.errors; nowField.value = allValues[name]; nowField.validating = false; nowField.dirty = false; nowAllFields[name] = nowField; } }); _this5.setFields(nowAllFields); if (callback) { if (expired.length) { expired.forEach(function (_ref3) { var name = _ref3.name; var fieldErrors = [{ message: name + ' need to revalidate', field: name }]; (0, _lodash6["default"])(errorsGroup, name, { expired: true, errors: fieldErrors }); }); } callback((0, _utils.isEmptyObject)(errorsGroup) ? null : errorsGroup, _this5.getFieldsValue((0, _utils.flatFieldNames)(fieldNames))); } }); }, // 调用validateFieldsInternal方法校验表单,参数ns为各表单项的name,opt校验配置,cb回调函数 validateFields: function validateFields(ns, opt, cb) { var _this6 = this; var _getParams = (0, _utils.getParams)(ns, opt, cb), names = _getParams.names, callback = _getParams.callback, options = _getParams.options; var fieldNames = names || this.getValidFieldsName(); var fields = fieldNames.map(function (name) { var fieldMeta = _this6.getFieldMeta(name); if (!(0, _utils.hasRules)(fieldMeta.validate)) { return null; } var field = _this6.getField(name); field.value = _this6.getFieldValue(name); return field; }).filter(function (f) { return !!f; }); if (!fields.length) { if (callback) { callback(null, this.getFieldsValue((0, _utils.flatFieldNames)(fieldNames))); } return; } if (!('firstFields' in options)) { options.firstFields = fieldNames.filter(function (name) { var fieldMeta = _this6.getFieldMeta(name); return !!fieldMeta.validateFirst; }); } this.validateFieldsInternal(fields, { fieldNames: fieldNames, options: options }, callback); }, // 判断表单项是否在校验过程中 isFieldValidating: function isFieldValidating(name) { return this.getFieldMember(name, 'validating'); }, // 判断表单中是否有某个表单项在校验过程中 isFieldsValidating: function isFieldsValidating(ns) { var _this7 = this; var names = ns || this.getValidFieldsName(); return names.some(function (n) { return _this7.isFieldValidating(n); }); }, // 判断表单的提交状态submitting isSubmitting: function isSubmitting() { return this.state.submitting; }, // 设置表单的提交状态submitting为真值,提交完成后执行callback回调,提交状态submitting改为否值 submit: function submit(callback) { var _this8 = this; var fn = function fn() { _this8.setState({ submitting: false }); }; this.setState({ submitting: true }); callback(fn); }, // 重置表单,各表单项的值、校验文案均清空 resetFields: function resetFields(ns) { var newFields = {}; var fields = this.fields; var changed = false; var names = ns || Object.keys(fields); names.forEach(function (name) { var field = fields[name]; if (field && 'value' in field) { changed = true; newFields[name] = {}; } }); if (changed) { this.setFields(newFields); } }, render: function render() { // 向下游WrappedComponent组件添加this.props.form工具函数集 var formProps = (0, _defineProperty3["default"])({}, formPropName, this.getForm()); // 向下游WrappedComponent组件添加ref属性 if (withRef) { formProps.ref = 'wrappedComponent'; } var props = mapProps.call(this, (0, _extends3["default"])({}, formProps, this.props)); return _react2["default"].createElement(WrappedComponent, props); } }); // 将WrappedComponent的非react静态方法拷贝给Form,何种意义??? return (0, _utils.argumentContainer)(Form, WrappedComponent); } return decorate; } exports["default"] = createBaseForm; module.exports = exports['default'];
2.createForm.js
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.mixin = undefined; var _createBaseForm = require('./createBaseForm'); var _createBaseForm2 = _interopRequireDefault(_createBaseForm); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var mixin = exports.mixin = { getForm: function getForm() { return { getFieldsValue: this.getFieldsValue, getFieldValue: this.getFieldValue, getFieldInstance: this.getFieldInstance, setFieldsValue: this.setFieldsValue, setFields: this.setFields, setFieldsInitialValue: this.setFieldsInitialValue, getFieldDecorator: this.getFieldDecorator, getFieldProps: this.getFieldProps, getFieldError: this.getFieldError, isFieldValidating: this.isFieldValidating, isFieldsValidating: this.isFieldsValidating, isSubmitting: this.isSubmitting, submit: this.submit, validateFields: this.validateFields, resetFields: this.resetFields }; } }; function createForm(options) { return (0, _createBaseForm2["default"])(options, [mixin]); } exports["default"] = createForm;
createDomForm.js
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _createBaseForm = require('./createBaseForm'); var _createBaseForm2 = _interopRequireDefault(_createBaseForm); var _createForm = require('./createForm'); var _utils = require('./utils'); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _domScrollIntoView = require('dom-scroll-into-view'); var _domScrollIntoView2 = _interopRequireDefault(_domScrollIntoView); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // 获取样式 function computedStyle(el, prop) { var getComputedStyle = window.getComputedStyle; var style = // If we have getComputedStyle getComputedStyle ? // Query it // TODO: From CSS-Query notes, we might need (node, null) for FF getComputedStyle(el) : // Otherwise, we are in IE and use currentStyle el.currentStyle; if (style) { return style[ // Switch to camelCase for CSSOM // DEV: Grabbed from jQuery // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 prop.replace(/-(\w)/gi, function (word, letter) { return letter.toUpperCase(); })]; } return undefined; } // 获取设置overflow样式的容器节点 function getScrollableContainer(n) { var node = n; var nodeName = void 0; /* eslint no-cond-assign:0 */ while ((nodeName = node.nodeName.toLowerCase()) !== 'body') { var overflowY = computedStyle(node, 'overflowY'); if (overflowY === 'auto' || overflowY === 'scroll') { return node; } node = node.parentNode; } return nodeName === 'body' ? node.ownerDocument : node; } var mixin = { // createBaseForm模块中往下游组件传递this.props.form工具函数集 // 提供getFieldProps、getFieldDecorator、validateFields、validateFieldsAndScroll、setFields等方法 getForm: function getForm() { return (0, _extends3["default"])({}, _createForm.mixin.getForm.call(this), { validateFieldsAndScroll: this.validateFieldsAndScroll }); }, validateFieldsAndScroll: function validateFieldsAndScroll(ns, opt, cb) { var _this = this; var _getParams = (0, _utils.getParams)(ns, opt, cb), names = _getParams.names, callback = _getParams.callback, options = _getParams.options; var newCb = function newCb(error, values) { if (error) { var firstNode = void 0; var firstTop = void 0; for (var name in error) { if (error.hasOwnProperty(name)) { var instance = _this.getFieldInstance(name); if (instance) { var node = _reactDom2["default"].findDOMNode(instance); var top = node.getBoundingClientRect().top; if (firstTop === undefined || firstTop > top) { firstTop = top; firstNode = node; } } } } if (firstNode) { var c = options.container || getScrollableContainer(firstNode); (0, _domScrollIntoView2["default"])(firstNode, c, (0, _extends3["default"])({ onlyScrollIfNeeded: true }, options.scroll)); } } if (typeof callback === 'function') { callback(error, values); } }; return this.validateFields(names, options, newCb); } }; function createDOMForm(option) { return (0, _createBaseForm2["default"])((0, _extends3["default"])({}, option), [mixin]); } exports["default"] = createDOMForm; module.exports = exports['default'];
utils.js
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _createBaseForm = require('./createBaseForm'); var _createBaseForm2 = _interopRequireDefault(_createBaseForm); var _createForm = require('./createForm'); var _utils = require('./utils'); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _domScrollIntoView = require('dom-scroll-into-view'); var _domScrollIntoView2 = _interopRequireDefault(_domScrollIntoView); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } // 获取样式 function computedStyle(el, prop) { var getComputedStyle = window.getComputedStyle; var style = // If we have getComputedStyle getComputedStyle ? // Query it // TODO: From CSS-Query notes, we might need (node, null) for FF getComputedStyle(el) : // Otherwise, we are in IE and use currentStyle el.currentStyle; if (style) { return style[ // Switch to camelCase for CSSOM // DEV: Grabbed from jQuery // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 prop.replace(/-(\w)/gi, function (word, letter) { return letter.toUpperCase(); })]; } return undefined; } // 获取设置overflow样式的容器节点 function getScrollableContainer(n) { var node = n; var nodeName = void 0; /* eslint no-cond-assign:0 */ while ((nodeName = node.nodeName.toLowerCase()) !== 'body') { var overflowY = computedStyle(node, 'overflowY'); if (overflowY === 'auto' || overflowY === 'scroll') { return node; } node = node.parentNode; } return nodeName === 'body' ? node.ownerDocument : node; } var mixin = { // createBaseForm模块中往下游组件传递this.props.form工具函数集 // 提供getFieldProps、getFieldDecorator、validateFields、validateFieldsAndScroll、setFields等方法 getForm: function getForm() { return (0, _extends3["default"])({}, _createForm.mixin.getForm.call(this), { validateFieldsAndScroll: this.validateFieldsAndScroll }); }, validateFieldsAndScroll: function validateFieldsAndScroll(ns, opt, cb) { var _this = this; var _getParams = (0, _utils.getParams)(ns, opt, cb), names = _getParams.names, callback = _getParams.callback, options = _getParams.options; var newCb = function newCb(error, values) { if (error) { var firstNode = void 0; var firstTop = void 0; for (var name in error) { if (error.hasOwnProperty(name)) { var instance = _this.getFieldInstance(name); if (instance) { var node = _reactDom2["default"].findDOMNode(instance); var top = node.getBoundingClientRect().top; if (firstTop === undefined || firstTop > top) { firstTop = top; firstNode = node; } } } } if (firstNode) { var c = options.container || getScrollableContainer(firstNode); (0, _domScrollIntoView2["default"])(firstNode, c, (0, _extends3["default"])({ onlyScrollIfNeeded: true }, options.scroll)); } } if (typeof callback === 'function') { callback(error, values); } }; return this.validateFields(names, options, newCb); } }; function createDOMForm(option) { return (0, _createBaseForm2["default"])((0, _extends3["default"])({}, option), [mixin]); } exports["default"] = createDOMForm; module.exports = exports['default'];
index.js
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.createForm = undefined; var _createForm = require('./createForm'); var _createForm2 = _interopRequireDefault(_createForm); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } exports.createForm = _createForm2["default"]; // export this package's api
3.hoist-non-react-statics模块用于拷贝某组件的非react静态方法
/** * Copyright 2015, Yahoo! Inc. * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ 'use strict'; var REACT_STATICS = { childContextTypes: true, contextTypes: true, defaultProps: true, displayName: true, getDefaultProps: true, mixins: true, propTypes: true, type: true }; var KNOWN_STATICS = { name: true, length: true, prototype: true, caller: true, arguments: true, arity: true }; var isGetOwnPropertySymbolsAvailable = typeof Object.getOwnPropertySymbols === 'function'; // 将sourceComponent的非react静态方法拷贝给targetComponent,REACT_STATICS、KNOWN_STATICS、customStatics中的除外 module.exports = function hoistNonReactStatics(targetComponent, sourceComponent, customStatics) { if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components var keys = Object.getOwnPropertyNames(sourceComponent); /* istanbul ignore else */ if (isGetOwnPropertySymbolsAvailable) { keys = keys.concat(Object.getOwnPropertySymbols(sourceComponent)); } for (var i = 0; i < keys.length; ++i) { if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]] && (!customStatics || !customStatics[keys[i]])) { try { targetComponent[keys[i]] = sourceComponent[keys[i]]; } catch (error) { } } } } return targetComponent; };
相关推荐
STM32F4-Discovery_FW_V1.1.0.zip是一个与STM32F4微控制器相关的固件库,主要用于开发基于STM32F4系列的探索板(STM32F4-Discovery)。该固件库包含了实现特定功能的源代码、头文件和其他必要的资源,帮助开发者快速...
mkl_random-1.1.0-cp35-cp35m-win32
1. 下载并解压资源包:首先从官方仓库下载`hyperledger-fabric-linux-amd64-1.1.0-rc1.tar.gz`,然后使用`tar -zxvf hyperledger-fabric-linux-amd64-1.1.0-rc1.tar.gz`命令进行解压。 2. 配置环境变量:解压后,你...
《Hyperledger Fabric 1.1.0:深入解析与应用》 Hyperledger Fabric是Linux基金会主导的开源项目,是企业级区块链技术的重要组成部分,尤其在金融、供应链、物联网等领域有广泛应用。本文将针对"hyperledger-fabric...
arcore-android-sdk-v1.1.0.zip,arcore-unity-sdk-v1.1.0.unitypackage,arcore-unreal-sdk-v1.1.0.zip 不需要多说了吧
v1.1.0版本后已经移除了网易云的支持,且仅支持洛雪PC端v2.6.0/移动端v1.2.0及以后的版本。
《商业源码-编程源码-Shang Blog 1.1.0 Final免安装版源码.zip》是一款基于特定编程语言开发的博客系统源代码,它提供了无需安装即可使用的便利性。这个压缩包中的核心文件“Shang Blog 1.1.0 Final免安装版源码”...
pytorch-1.1.0-py3.7_cuda100_cudnn7_1.tar.bz2
et_xmlfile-1.1.0.tar
在“洛雪音乐助手自定义音源 v1.1.0”这个版本中,用户不再受限于预设的音乐库,而是能够通过添加不同的音源来拓宽音乐搜索范围,享受更加个性化的音乐体验。 自定义音源是洛雪音乐助手的核心功能之一。它允许用户...
赠送原API文档:scala-parser-combinators_2.12-1.1.0-javadoc.jar; 赠送源代码:scala-parser-combinators_2.12-1.1.0-sources.jar; 赠送Maven依赖信息文件:scala-parser-combinators_2.12-1.1.0.pom; 包含翻译...
python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载 beautifulsoup4==4.11.1 bs4==0.0.1 certifi==2021.5.30 cffi==1.15.0 charset-normalizer==2.0.12 cryptography==37.0.2 cycler=...
atmosphere-gwt-client20-1.1.0.rc1-sources.jar
atmosphere-compat-jbossweb-1.1.0.rc4-sources.jar
atmosphere-compat-jbossweb-1.1.0.rc3-sources.jar
atmosphere-compat-jbossweb-1.1.0.rc1-sources.jar
atmosphere-compat-tomcat7-1.1.0.rc4-sources.jar
atmosphere-compat-tomcat7-1.1.0.rc3-sources.jar
atmosphere-compat-tomcat7-1.1.0.rc1-sources.jar
aliyun-java-sdk-dysmsapi-1.1.0.jar 最新下载的 阿里云短信服务器所需jar包之一,core包可以在maven找到不再上传 <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-dysmsapi --> ...