UNPKG

isu-element

Version:

Polymer components for building web apps.

373 lines (344 loc) 9.6 kB
import '../isu-loading.js'; /** * @polymerBehavior */ export const BaseBehavior = { /** * 判断第一个参数是否与后面的某个参数相等, 使用Object.is() 进行判断 * @param {...*} args * @return {boolean} */ isOneOf(...args) { if (Array.isArray(args) && args.length > 0) { const target = args[0]; return args.slice(1).some(arg => Object.is(arg, target)); } return false; }, /** * 判断两个值是否相等,使用 `Object.is` 判断。 * @param {*} left * @param {*} right * @returns {Boolean} */ isEqual(left, right) { return Object.is(left, right); }, /** * 判断传入参数两两是否全部相等 * @param args * @return {boolean} */ allEqual(...args) { for(let i = 0, len = args.length; i < len; i = i + 2) { if(i + 1 >= len || !Object.is(args[i], args[i + 1])) return false; } return true; }, /** * 判断传入参数两两是否存在一对相等 * @param args * @return {boolean} */ someEqual(...args) { for(let i = 0, len = args.length - 1; i < len; i = i + 2) { if(Object.is(args[i], args[i + 1])) return true; } return false; }, /** * 函数判断 * @param {*} fn * @returns {Boolean} */ isFunction(fn) { return Function.prototype.isPrototypeOf(fn); }, /** * Return the first giving arg which is not ``undefined``, ``null``, ``NaN`` , ``false`` ,``0`` or ``''``. * * eg. * ``` * orElse(undefined, null, "foo") // "foo" * orElse(0, 1) // 1 * orElse("bar", "foo") // "bar" * ``` * @param {...*} args * @returns {*} */ orElse(...args) { const [first, ...rest] = args; return rest.length === 0 ? first : (first || this.orElse(...rest)); }, /** * 通过key查询对象中的值 * @param {Object} model * @param {String} key * @param {String} defVal 支持任何符合json格式的字符串 * @returns {*} */ getValueByKey(model, key, defVal = "") { return (model && (key in model)) ? model[key] : defVal; }, /** * 等价于 model[key1 || key2 || ...] * @param {Object} model * @param {...String} keys * @returns {*} */ getValueOrElse(model, ...keys) { const key = this.orElse(...keys); return this.getValueByKey(model, key); }, /** * 等价于 model[key1 || key2 || ...] 如果找不到值,返回null * @param {Object} model * @param {...String} keys * @returns {*} */ getValueOrElseNull(model, ...keys) { const key = this.orElse(...keys); return this.getValueByKey(model, key, null); }, /** * 等价于 model[key1 || key2 || ...] 如果找不到值,返回 undefined * @param {Object} model * @param {...String} keys * @returns {*} */ getValueOrElseUndefined(model, ...keys) { const key = this.orElse(...keys); return (model && (key in model)) ? model[key] : undefined; }, /** * 解析json串,如果传入参数不符合json标准,则原样返回 * @param val * @return {*} */ resolveJsonValue(val) { try { if (typeof val === 'string') { return JSON.parse(val) } } catch (e) { } return val; }, /** * 通过路径获取对象字段值 * @param {Object} model eg. { foo: { bar: 1} } * @param {String} path eg. "foo.bar" * @param {*} defVal 如果传入的是符合json格式的字符串,会返回JSON.parse处理的结果 * @returns {*} */ getValueByPath(model, path = '', defVal) { if (!model) return this.resolveJsonValue(defVal); const splits = path.split('.'); let copy = model; for (let key of splits) { if (!copy[key]) return this.resolveJsonValue(defVal); copy = copy[key]; } return copy; }, /** * 通过路径设置对象字段值, 如果路径不存在,会抛出异常 * @param model * @param path * @param value * @return {*} */ setValueByPath(model, path, value) { const paths = String(path).split("."); let tmp = model, ctx, key; for (key of paths) { if (key in tmp) { ctx = tmp; tmp = tmp[key]; } else { throw new Error(`path ${key} not found in the giving object`); } } ctx[key] = value; return model; }, /** * 根据路径生成对象,如 path='a.b' 返回 {a: {b: {}}}, 如果指定了target, 会在target上生成不存在的key * @param path * @param target */ mkObject(path = '', target = {}) { const paths = String(path).split("."); if (String(path).length > 0) { paths.reduce((res, p) => { if (!(p in res && typeof res[p] === 'object')) res[p] = {}; return res[p]; }, target); } return target; }, /** * To boolean. * @param {*} val */ toBoolean(val) { return !!val; }, /** * check if there's a truthy in the giving args * @param {*} val */ isExistTruthy(...args) { return args.some(arg => !!arg) }, /** * Check if an array is empty. * @param arr * @returns {boolean} */ isArrayEmpty(arr = []) { return arr.length === 0; }, /** * 简单数学运算 * @param first * @param op * @param nums * @returns {*} */ calc(first, op, ...nums) { switch (op) { case '+': return nums.reduce((res, num) => res + num, first); case '-': return nums.reduce((res, num) => res - num, first); case '*': return nums.reduce((res, num) => res * num, first); case '/': return nums.reduce((res, num) => res / num, first); case '%': return nums.reduce((res, num) => res % num, first); default: return ''; } }, toggleClass(target, className) { if (target instanceof Element) { if (target.classList.contains(className)) { target.classList.remove(className); } else { target.classList.add(className); } } }, /** * 添加loading */ showLoading() { let loadingDiv = document.body.querySelector("#isu-loading"); if (!loadingDiv) { loadingDiv = document.createElement("isu-loading"); loadingDiv.setAttribute("id", "isu-loading"); loadingDiv.noCancelOnOutsideClick = true; loadingDiv.noCancelOnEscKey = true; // loadingDiv.withBackdrop = true; document.body.appendChild(loadingDiv); } this.async(function () { loadingDiv.open(); }, 0); }, /** * 消除loading */ hideLoading() { this.async(function () { const loadingDiv = document.body.querySelector("#isu-loading"); loadingDiv && loadingDiv.close(); }, 0); }, throwNotFoundError(string) { throw new TypeError(string + " should not be undefined.") }, deepClone(obj) { return obj == null || typeof (obj) !== "object" ? obj : JSON.parse(JSON.stringify(obj)); }, optional(bool, trueReturn, falseReturn = '') { return bool ? trueReturn : falseReturn; }, /** * 用法: * this.groupBy(array, 'a', 'nogroup'); * this.groupBy(array, (item) => item.a || 'nogroup'); * * 对数组进行分组,如给定[{a: 'group1', b: 2}, {a: 'group1', b: 4}, {a: 'group2', b: 5}] 返回 { 'group1': [{a: 'group1', b: 2}, {a: 'group1', b: 4}], 'group2': [ {a: 'group2', b: 5}] } * @param array * @param iteratee, The iteratee to transform keys.,如 'bar', 或 'foo.bar' 或 Function * @param defaultGroup, 当指定的分组字段不存在时,归类到的默认分组 * @return Object */ groupBy(array, iteratee, defaultGroup = 'wilding') { let valueResolver, args; if (this.isFunction(iteratee)) { valueResolver = iteratee; args = []; } else { valueResolver = this.getValueByPath; args = [iteratee, defaultGroup]; } return array.reduce((res, item) => { const val = valueResolver.call(this, item, ...args); const group = res[val] || []; group.push(item); res[val] = group; return res; }, {}); }, /** * this.partition([1,2,3], item => item > 2); 返回 [[3], [1, 2]] * this.partition([{a: 1}, {a: 2}], {a: 1}); 返回 [[{a: 1}], [{a: 2}]] *this.partition([{a: 1}, {a: 2}], 'a'); 返回 [[{a: 1}, {a: 2}], []] * * Creates an array of elements split into two groups, the first of which contains elements predicate returns truthy for, the second of which contains elements predicate returns falsey for. * @param array * @param predicate * @return */ partition(array, predicate) { let _predicate; if (this.isFunction(predicate)) { _predicate = predicate; } else if (Object.prototype.isPrototypeOf(predicate)) { _predicate = (item) => Object.entries(predicate).every(([key, value]) => item[key] === value) } else if (typeof predicate === 'string') { _predicate = (item) => item[predicate]; } else { throw new TypeError(`Unsupported predicate type ${typeof predicate}`) } return array.reduce((res, item) => { if (_predicate.call(this, item)) { res[0].push(item); } else { res[1].push(item); } return res; }, [[], []]); }, /** * get date-invalid attribute * * @param * @return */ getInvalidAttribute() { !this.validate() ? this.setAttribute("data-invalid", "") : this.removeAttribute("data-invalid"); }, /** * check the validate, override by the child component * * @param * @return */ validate() { } };