@sms-frontend/components
Version:
SMS Design React UI Library.
356 lines (355 loc) • 14.7 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import get from 'lodash/get';
import setWith from 'lodash/setWith';
import has from 'lodash/has';
import omit from 'lodash/omit';
import { cloneDeep, set, iterativelyGetKeys } from './utils';
import { isArray, isObject, isString } from '../_util/is';
import promisify from './promisify';
var Store = /** @class */ (function () {
function Store() {
var _this = this;
this.registerFields = [];
// 和formControl 的 touched属性不一样。 只要被改过的字段,这里就会存储。并且不会跟随formControl被卸载而清除。
// reset 的时候清除
this.touchedFields = {};
this.store = {};
this.initialValues = {};
this.callbacks = {};
this.innerSetCallbacks = function (values) {
_this.callbacks = values;
};
// 收集所有control字段,并在组件卸载时移除
this.registerField = function (item) {
_this.registerFields.push(item);
return function () {
_this.registerFields = _this.registerFields.filter(function (x) { return x !== item; });
};
};
// hasField为true时,只返回传入field属性的control实例
this.getRegistedFields = function (hasField) {
if (hasField) {
return _this.registerFields.filter(function (control) { var _a; return control.hasFieldProps() && !((_a = control.props) === null || _a === void 0 ? void 0 : _a.isFormList); });
}
return _this.registerFields;
};
// 获取props.field === field 的contorl组件。
this.getRegistedField = function (field) {
return _this.registerFields.filter(function (x) { return x.props.field === field; })[0];
};
// 通知所有的formitem进行更新。
// setfielValue: 外部调用setFieldsValue (setFieldValue等)方法触发更新
// innerSetValue: 控件例如Input,通过onChange事件触发的更新
// reset: 重置
this.notify = function (type, info) {
if (type === 'setFieldValue' || (type === 'innerSetValue' && !info.ignore)) {
// type = reset时,在reset函数里处理
// if info.field is a[0], get a.0
_this._pushTouchField(info.changeValues
? iterativelyGetKeys(info.changeValues)
: _this._getIterativelyKeysByField(info.field));
}
_this.registerFields.forEach(function (item) {
item.onStoreChange &&
item.onStoreChange(type, __assign(__assign({}, info), { current: _this.store }));
});
};
this.innerSetInitialValues = function (values) {
if (!values)
return;
_this.initialValues = cloneDeep(values);
Object.keys(values).forEach(function (field) {
set(_this.store, field, values[field]);
});
};
this.innerSetInitialValue = function (field, value) {
if (!field)
return;
_this.initialValues[field] = value;
// 组件在创建的时候,需要判断store里存的对应field的值是否生效。只要没有被操作过(touchedFields里不存在),就生效
if (!_this._inTouchFields(field)) {
set(_this.store, field, get(_this.initialValues, field));
}
};
/**
*
* 内部使用,更新value,会同时触发onChange 和 onValuesChange
* @options.isFormList 强制更新field对应的组件包括其子组件,form
*/
this.innerSetFieldValue = function (field, value, options) {
var _a, _b, _c;
if (!field)
return;
var prev = cloneDeep(_this.store);
set(_this.store, field, value);
_this.triggerValuesChange((_a = {}, _a[field] = value, _a));
_this.triggerTouchChange((_b = {}, _b[field] = value, _b));
_this.notify('innerSetValue', __assign(__assign({ prev: prev, field: field }, options), { changeValues: (_c = {}, _c[field] = value, _c) }));
};
// 内部使用
this.innerGetStore = function () {
return _this.store;
};
// 获取所有被操作过的字段
this.getTouchedFields = function () {
return _this.getRegistedFields(true)
.filter(function (item) {
return item.isTouched();
})
.map(function (x) { return x.props.field; });
};
// 外部调用设置表单字段值
this.setFieldValue = function (field, value) {
var _a;
if (!field)
return;
_this.setFields((_a = {},
_a[field] = { value: value },
_a));
};
// 外部调用,设置多个表单控件的值
this.setFieldsValue = function (values) {
if (isObject(values)) {
var fields = Object.keys(values);
var obj_1 = {};
fields.forEach(function (field) {
obj_1[field] = {
value: values[field],
};
});
_this.setFields(obj_1);
}
};
// 外部调用,设置多个表单控件的值,以及 error,touch 信息。
this.setFields = function (obj) {
var fields = Object.keys(obj);
var changeValues = {};
fields.forEach(function (field) {
var _a;
var item = obj[field];
var prev = cloneDeep(_this.store);
if (item) {
var info = {};
if ('error' in item) {
info.errors = item.error;
}
if ('warning' in item) {
info.warnings = item.warning;
}
if ('touched' in item) {
info.touched = item.touched;
}
if ('value' in item) {
set(_this.store, field, item.value);
changeValues[field] = item.value;
}
_this.notify('setFieldValue', {
data: info,
prev: prev,
field: field,
changeValues: (_a = {}, _a[field] = item.value, _a),
});
}
});
_this.triggerValuesChange(changeValues);
};
this.getFieldValue = function (field) {
return get(_this.store, field);
};
// 获取单个字段的错误信息。
this.getFieldError = function (field) {
var item = _this.getRegistedField(field);
return item ? item.getErrors() : null;
};
// 获取传入字段/全部的错误信息
this.getFieldsError = function (fields) {
var errors = {};
if (isArray(fields)) {
fields.map(function (field) {
var error = _this.getFieldError(field);
if (error) {
errors[field] = error;
}
});
}
else {
_this.getRegistedFields(true).forEach(function (item) {
if (item.getErrors()) {
errors[item.props.field] = item.getErrors();
}
});
}
return errors;
};
this.getFields = function () {
var values = cloneDeep(_this.store);
return values;
};
this.getFieldsValue = function (fields) {
var values = {};
if (isArray(fields)) {
fields.forEach(function (key) {
set(values, key, _this.getFieldValue(key));
});
return values;
}
_this.getRegistedFields(true).forEach(function (_a) {
var field = _a.props.field;
var value = get(_this.store, field);
set(values, field, value);
});
return values;
};
this.resetFields = function (fieldKeys) {
var prev = cloneDeep(_this.store);
var fields = isString(fieldKeys) ? [fieldKeys] : fieldKeys;
if (fields && isArray(fields)) {
var changeValues_1 = {};
fields.forEach(function (field) {
set(_this.store, field, _this.initialValues[field]);
changeValues_1[field] = get(_this.store, field);
});
_this.triggerValuesChange(changeValues_1);
_this.notify('reset', { prev: prev, field: fields });
_this._popTouchField(fields);
}
else {
var newValues_1 = {};
var changeValues_2 = cloneDeep(_this.store);
Object.keys(_this.initialValues).forEach(function (field) {
set(newValues_1, field, _this.initialValues[field]);
});
_this.store = newValues_1;
_this.getRegistedFields(true).forEach(function (item) {
var key = item.props.field;
set(changeValues_2, key, get(_this.store, key));
});
_this.triggerValuesChange(changeValues_2);
_this._popTouchField();
_this.notify('reset', { prev: prev, field: Object.keys(changeValues_2) });
}
};
this.validate = promisify(function (fieldsOrCallback, cb) {
var callback = function () { };
var controlItems = _this.getRegistedFields(true);
if (isArray(fieldsOrCallback) && fieldsOrCallback.length > 0) {
controlItems = controlItems.filter(function (x) { return fieldsOrCallback.indexOf(x.props.field) > -1; });
callback = cb || callback;
}
else if (typeof fieldsOrCallback === 'function') {
callback = fieldsOrCallback;
}
var promises = controlItems.map(function (x) { return x.validateField(); });
Promise.all(promises).then(function (result) {
var errors = {};
var values = {};
result.map(function (x) {
if (x.error) {
errors = __assign(__assign({}, errors), x.error);
}
set(values, x.field, x.value);
});
if (Object.keys(errors).length) {
var onValidateFail = _this.callbacks.onValidateFail;
onValidateFail && onValidateFail(errors);
callback && callback(errors, cloneDeep(values));
}
else {
callback && callback(null, cloneDeep(values));
}
});
});
this.submit = function () {
_this.validate(function (errors, values) {
if (!errors) {
var onSubmit = _this.callbacks.onSubmit;
onSubmit && onSubmit(values);
}
else {
var onSubmitFailed = _this.callbacks.onSubmitFailed;
onSubmitFailed && onSubmitFailed(errors);
}
});
};
}
Store.prototype.triggerValuesChange = function (value) {
if (value && Object.keys(value).length) {
var onValuesChange = this.callbacks.onValuesChange;
onValuesChange && onValuesChange(value, this.getFields());
}
};
Store.prototype.triggerTouchChange = function (value) {
if (value && Object.keys(value).length) {
var onChange = this.callbacks.onChange;
onChange && onChange(value, this.getFields());
}
};
Store.prototype._getIterativelyKeysByField = function (field) {
if (!field) {
return [];
}
var fields = [].concat(field);
var keys = fields
.map(function (item) { return iterativelyGetKeys(set({}, item, undefined)); })
.reduce(function (total, next) {
return total.concat(next);
}, []);
return __spreadArray([field], __read(keys), false);
};
Store.prototype._inTouchFields = function (field) {
var _this = this;
var keys = this._getIterativelyKeysByField(field);
// return fields.some((item) => has(fieldObj, item));
return keys.some(function (item) { return has(_this.touchedFields, item); });
};
Store.prototype._popTouchField = function (field) {
if (field === undefined) {
this.touchedFields = {};
}
var keys = this._getIterativelyKeysByField(field);
this.touchedFields = omit(this.touchedFields, keys);
};
Store.prototype._pushTouchField = function (field) {
var _this = this;
[].concat(field).forEach(function (key) {
setWith(_this.touchedFields, key, undefined, Object);
});
};
return Store;
}());
export default Store;