UNPKG

@antmjs/vantui

Version:

一套适用于Taro3及React的vantui组件库

597 lines (592 loc) 22.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _reactDom = require("react-dom"); var _validator = require("../../common/validator"); /* eslint-disable @typescript-eslint/ban-ts-comment */ /* 对外接口 */ var formInstanceApi = ['setCallback', 'dispatch', 'registerValidateFields', 'resetFields', 'setFields', 'setFieldsValue', 'getFieldsValue', 'getFieldValue', 'validateFields', 'submit', 'unRegisterValidate', 'registerRequiredMessageCallback', 'validateFieldValue', 'setErrorMessage']; var isReg = function isReg(value) { return value instanceof RegExp; }; var FormStore = /*#__PURE__*/function () { function FormStore(forceUpdate, defaultFormValue) { (0, _classCallCheck2.default)(this, FormStore); this.FormUpdate = forceUpdate; this.model = {}; this.control = {}; this.isSchedule = false; this.callback = {}; this.penddingValidateQueue = []; this.defaultFormValue = defaultFormValue || {}; this.requiredMessageCallback = undefined; this.multiLevelKeys = []; } (0, _createClass2.default)(FormStore, [{ key: "getForm", value: function getForm() { var _this = this; return formInstanceApi.reduce(function (map, item) { map[item] = _this[item].bind(_this); return map; }, {}); } }, { key: "registerRequiredMessageCallback", value: function registerRequiredMessageCallback(callback) { this.requiredMessageCallback = callback; } }, { key: "setCallback", value: function setCallback(callback) { if (callback) this.callback = callback; } }, { key: "setErrorMessage", value: function setErrorMessage(name_, message) { var name = Array.isArray(name_) ? name_.join('.') : name_; if (this.model[name]) { this.model[name].message = message; this.model[name].status = 'reject'; this.FormUpdate(); } else { console.error('form warning: setErrorMessage params.name is not register'); } } }, { key: "dispatch", value: function dispatch(action) { if (!action && (0, _typeof2.default)(action) !== 'object') return null; var type = action.type; for (var _len = arguments.length, arg = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { arg[_key - 1] = arguments[_key]; } if (~formInstanceApi.indexOf(type)) { // @ts-ignore return this[type].apply(this, arg); } else if (typeof this[type] === 'function') { // @ts-ignore return this[type].apply(this, arg); } } }, { key: "registerValidateFields", value: function registerValidateFields(name_, control, model) { var name = Array.isArray(name_) ? name_.join('.') : name_; var defaultFormValue_ = this.defaultFormValue; if (name.includes('.') && !model['mutiLevel']) { defaultFormValue_ = this.transformToSingleLevelData(this.defaultFormValue, name.split('.')[0]); } if (defaultFormValue_[name]) { if (!this.model[name] || this.model[name].value === undefined) { model['value'] = defaultFormValue_[name]; } } if (!model['value'] && this.model[name]) model['value'] = this.model[name].value; if (model['mutiLevel']) { if (!this.multiLevelKeys.includes(name)) { this.multiLevelKeys.push(name); } } if (!model['mutiLevel']) { var keyIndex = this.multiLevelKeys.indexOf(name); if (keyIndex > 0) { this.multiLevelKeys.splice(keyIndex, 1); } } var shouldUpdate = !this.model[name] || this.model[name].value === undefined; var validate = FormStore.createValidate(model); this.model[name] = validate; this.control[name] = control; if (shouldUpdate) { control === null || control === void 0 ? void 0 : control['changeValue'](); } } }, { key: "unRegisterValidate", value: function unRegisterValidate(name_) { var name = Array.isArray(name_) ? name_.join('.') : name_; delete this.model[name]; delete this.control[name]; } }, { key: "notifyChange", value: function notifyChange(name_, hiddenFormChange) { var name = Array.isArray(name_) ? name_.join('.') : name_; var controller = this.control[name]; if (controller) controller === null || controller === void 0 ? void 0 : controller.changeValue(); if (!hiddenFormChange) { var onChange = this.callback.onChange; if (onChange) { var value = this.model[name].value; onChange(FormStore.transformMultilevelData((0, _defineProperty2.default)({}, name, value)), this.getFieldsValue()); } } } }, { key: "setFields", value: function setFields(object) { if ((0, _typeof2.default)(object) !== 'object') return; this.transformModelToSingelLevelData(object, this.multiLevelKeys); for (var key in this.model) { var item = this.model[key]; this.setValueClearStatus(item, key, item.value, true); // 批量更新hiddenFormChange } var onChange = this.callback.onChange; if (onChange) { onChange(object, this.getFieldsValue()); } } }, { key: "setFieldsValue", value: function setFieldsValue(name_, modelValue) { var name = Array.isArray(name_) ? name_.join('.') : name_; var model = this.model[name]; if (!model) return false; if (toString.call(modelValue) === '[Object, object]' && modelValue.value) { var message = modelValue.message, rule = modelValue.rule, value = modelValue.value; if (message) model.message = message; if (rule) model.rule = rule; if (value && model.value === undefined) model.value = value; model.status = 'pendding'; this.validateFieldValue(name, true); } else { this.setValueClearStatus(model, name, modelValue); } } }, { key: "setValueClearStatus", value: function setValueClearStatus(model, name_, value, hiddenFormChange) { var name = Array.isArray(name_) ? name_.join('.') : name_; model['value'] = value; model['status'] = 'pendding'; this.notifyChange(name, hiddenFormChange); } // 扁平数据转多层数据结构 }, { key: "transformModelToSingelLevelData", value: // model数据结构扁平化 function transformModelToSingelLevelData(data, multiLevelKeys) { // eslint-disable-next-line @typescript-eslint/no-this-alias var that = this; function unitWork(curKey, dd) { if (toString.call(dd) === '[object Object]') { if (multiLevelKeys.includes(curKey)) { that.model[curKey].value = dd; } else { for (var key in dd) { var value = dd[key]; unitWork(curKey ? "".concat(curKey, ".").concat(key) : key, value); } } } else if (toString.call(dd) === '[object Array]') { if (multiLevelKeys.includes(curKey)) { that.model[curKey].value = dd; } else { for (var i = 0; i < dd.length; i++) { var _value = dd[i]; unitWork(curKey ? "".concat(curKey, ".").concat(i) : "".concat(i), _value); } } } else { if (that.model[curKey]) { that.model[curKey].value = dd; } } } unitWork('', data); } // 目标数据的多层数据扁平化 }, { key: "transformToSingleLevelData", value: function transformToSingleLevelData(data, targetKey) { var res = {}; var work = function work(prevKey, dd) { if (toString.call(dd) === '[object Object]') { for (var k in dd) { work(prevKey ? "".concat(prevKey, ".").concat(k) : k, dd[k]); } } else if (toString.call(dd) === '[object Array]') { for (var i = 0; i < dd.length; i++) { work(prevKey ? "".concat(prevKey, ".").concat(i) : i, dd[i]); } } else { res[prevKey] = dd; } }; for (var kk in data) { if (targetKey === kk) { work(kk, data[kk]); } } return res; } }, { key: "getFieldsValue", value: function getFieldsValue() { var _this2 = this; var formData = {}; Object.keys(this.model).forEach(function (modelName) { formData[modelName] = _this2.model[modelName].value; }); return FormStore.transformMultilevelData(formData); } }, { key: "resetFields", value: function resetFields() { var _this3 = this; Object.keys(this.model).forEach(function (modelName) { _this3.setValueClearStatus(_this3.model[modelName], modelName, null); }); } }, { key: "getFieldModel", value: function getFieldModel(name_) { var name = Array.isArray(name_) ? name_.join('.') : name_; var model = this.model[name]; return model ? model : {}; } }, { key: "getFieldValue", value: function getFieldValue(name_) { var name = Array.isArray(name_) ? name_.join('.') : name_; var model = this.model[name]; if (!model && this.defaultFormValue[name]) return this.defaultFormValue[name]; return model ? model.value : null; } }, { key: "validateFieldValue", value: function () { var _validateFieldValue = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(name_) { var _this4 = this; var forceUpdate, name, model, lastStatus, required, rules, value, status, i, rule, message, validateCallback, result, validationMessage, notify, _args = arguments; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: forceUpdate = _args.length > 1 && _args[1] !== undefined ? _args[1] : true; name = Array.isArray(name_) ? name_.join('.') : name_; model = this.model[name]; /* 记录上次状态 */ lastStatus = model === null || model === void 0 ? void 0 : model.status; if (model) { _context.next = 6; break; } return _context.abrupt("return", null); case 6: required = model.required, rules = model.rules, value = model.value; status = 'resolve'; _context.prev = 8; if (required && FormStore.isFieldNull(value)) { status = 'reject'; if (this.requiredMessageCallback) { this.model[name].message = this.requiredMessageCallback(this.model[name].label, name); } else { if (this.model[name].label) { this.model[name].message = this.model[name].label + '不能为空'; } else { this.model[name].message = '此处不能为空'; } } } i = 0; case 11: if (!(i < rules.length)) { _context.next = 50; break; } rule = rules[i].rule; message = rules[i].message; if (!(value || value === 0)) { _context.next = 47; break; } if (!isReg(rule)) { _context.next = 22; break; } status = rule.test(value) ? 'resolve' : 'reject'; if (!(status === 'reject')) { _context.next = 20; break; } this.model[name].message = message; return _context.abrupt("break", 50); case 20: _context.next = 47; break; case 22: if (!(typeof rule === 'function')) { _context.next = 47; break; } // 传统的回调函数形式 validateCallback = function validateCallback(callbackMessage) { _this4.model[name].message = callbackMessage; status = !callbackMessage ? 'resolve' : 'reject'; }; // 检查函数是否返回Promise,传入callback兼容同步回调 result = rule(value, validateCallback); if (!(0, _validator.isPromise)(result)) { _context.next = 44; break; } _context.prev = 26; // 规则函数返回Promise的情况 model.status = 'validating'; // 添加校验中的状态 _context.next = 30; return result; case 30: validationMessage = _context.sent; status = !validationMessage ? 'resolve' : 'reject'; if (!(status === 'reject')) { _context.next = 35; break; } this.model[name].message = validationMessage || message; return _context.abrupt("break", 50); case 35: _context.next = 42; break; case 37: _context.prev = 37; _context.t0 = _context["catch"](26); // 处理异步校验过程中的错误 status = 'reject'; this.model[name].message = (_context.t0 === null || _context.t0 === void 0 ? void 0 : _context.t0.message) || message || '校验失败'; return _context.abrupt("break", 50); case 42: _context.next = 47; break; case 44: // 执行规则函数 rule(value, validateCallback); // 如果回调没有被立即调用,可能是异步回调 // 但我们不能在这里等待它,因为可能永远不会被调用 if (!(status === 'reject')) { _context.next = 47; break; } return _context.abrupt("break", 50); case 47: i++; _context.next = 11; break; case 50: _context.next = 56; break; case 52: _context.prev = 52; _context.t1 = _context["catch"](8); // 捕获整个校验过程中的任何错误 status = 'reject'; this.model[name].message = (_context.t1 === null || _context.t1 === void 0 ? void 0 : _context.t1.message) || '校验过程发生错误'; case 56: model.status = status; if (lastStatus !== status || forceUpdate) { // 校验的时候不触发form change notify = this.notifyChange.bind(this, name, true); this.penddingValidateQueue.push(notify); } this.scheduleValidate(); return _context.abrupt("return", status); case 60: case "end": return _context.stop(); } }, _callee, this, [[8, 52], [26, 37]]); })); function validateFieldValue(_x) { return _validateFieldValue.apply(this, arguments); } return validateFieldValue; }() }, { key: "scheduleValidate", value: function scheduleValidate() { var _this5 = this; if (this.isSchedule) return; this.isSchedule = true; Promise.resolve().then(function () { (0, _reactDom.unstable_batchedUpdates)(function () { do { var notify = _this5.penddingValidateQueue.shift(); notify && notify(); } while (_this5.penddingValidateQueue.length > 0); _this5.isSchedule = false; }); }); } }, { key: "validateFields", value: function validateFields(callback) { var _this6 = this; // 使用Promise处理异步校验 setTimeout( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() { var errorsMess, modelNames, validationPromises, results; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: _context3.prev = 0; errorsMess = []; modelNames = Object.keys(_this6.model); // 等待所有字段的异步校验完成 validationPromises = modelNames.map( /*#__PURE__*/function () { var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(modelName) { var status; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return _this6.validateFieldValue(modelName, true); case 2: status = _context2.sent; if (!(status === 'reject')) { _context2.next = 5; break; } return _context2.abrupt("return", _this6.model[modelName].message); case 5: return _context2.abrupt("return", null); case 6: case "end": return _context2.stop(); } }, _callee2); })); return function (_x2) { return _ref2.apply(this, arguments); }; }()); // 收集所有错误信息 _context3.next = 6; return Promise.all(validationPromises); case 6: results = _context3.sent; results.forEach(function (message) { if (message) errorsMess.push(message); }); // 调用回调函数 callback(errorsMess, _this6.getFieldsValue()); _context3.next = 15; break; case 11: _context3.prev = 11; _context3.t0 = _context3["catch"](0); console.error('表单校验过程发生错误:', _context3.t0); callback(['表单校验过程发生错误'], _this6.getFieldsValue()); case 15: case "end": return _context3.stop(); } }, _callee3, null, [[0, 11]]); }))); } }, { key: "submit", value: function submit(cb) { var _this7 = this; this.validateFields(function (errorMess) { var _this7$callback = _this7.callback, onFinish = _this7$callback.onFinish, onFinishFailed = _this7$callback.onFinishFailed; var fieldValues = _this7.getFieldsValue(); var errs = errorMess.length ? errorMess : null; cb && cb(errs, fieldValues); if (errs) { onFinishFailed && typeof onFinishFailed === 'function' && onFinishFailed(errs); return; } onFinish && typeof onFinish === 'function' && onFinish(errs, _this7.getFieldsValue()); }); } }], [{ key: "createValidate", value: function createValidate(validateModal) { var value = validateModal.value, required = validateModal.required, rules = validateModal.rules, label = validateModal.label; return { value: value, rules: Array.isArray(rules) ? rules : [rules], required: required || false, status: 'pendding', label: label }; } }, { key: "isFieldNull", value: function isFieldNull(value) { return value === undefined || value === '' || value === null || Array.isArray(value) && value.length === 0; } }, { key: "transformMultilevelData", value: function transformMultilevelData(data) { var keys = Object.keys(data); var hasMultiLevel = keys.some(function (item) { return item.includes('.'); }); if (hasMultiLevel) { var res = {}; for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (key) { if (!(key !== null && key !== void 0 && key.includes('.'))) { res[key] = data[key]; } else { var ks = key.split('.'); var p = res; for (var j = 0; j < ks.length; j++) { var k = ks[j]; if (p[k] && j !== ks.length - 1) { p = p[k]; } else if (!p[k] && j !== ks.length - 1) { var nextK = ks[j + 1]; if (!isNaN(Number(nextK)) && typeof Number(nextK) === 'number') { p[k] = []; } else if (typeof nextK === 'string') { p[k] = {}; } p = p[k]; } else { p[k] = data[key]; } } } } } return res; } else { return data; } } }]); return FormStore; }(); var _default = FormStore; exports.default = _default;