UNPKG

ewm

Version:

小程序原生插件

187 lines 7.89 kB
import { isEmptyObj, IsShortProperties } from "../../core/_api"; import { getDataOnPath, parseMultiDataPaths } from "./data-path"; import { create, unwrap } from "./data-tracer"; import { deepEqual } from "./fast-deep-equal"; import { rfdc } from "./rfdc"; const deepClone = rfdc({ proto: true }); function getDefaultValue(propertiesType) { switch (propertiesType) { case String: return ""; case Number: return 0; case Array: return []; case Object: return {}; case Boolean: return false; default: throw console.error("怎么可能呢"); } } function getDefaultValueOfProperties(propertiesDef) { const propertiesValue = {}; if (propertiesDef) { for (const key in propertiesDef) { const val = propertiesDef[key]; if (IsShortProperties(val)) { propertiesValue[key] = getDefaultValue(val); } else if (val.value) { propertiesValue[key] = val.value; } else { propertiesValue[key] = getDefaultValue(val.type); } } } return propertiesValue; } function sort(missDepend) { const res = []; const list = Object.keys(missDepend); list.forEach((key, i) => { console.log(); if (i === 0) { res.push(key); } if (i > 0) { if (missDepend[key].length < missDepend[list[i - 1]].length) { res.unshift(key); } } }); return res; } let cacheId = 0; const computedCache = []; const watchCache = []; export const BComputedWatch = Behavior({ definitionFilter(options) { const computedDef = options.computed; const dataDef = (options.data || (options.data = {})); const propertiesDefaultValue = getDefaultValueOfProperties(options.properties); const allData = Object.assign(Object.assign({}, dataDef), propertiesDefaultValue); const curCacheId = cacheId++; if (computedDef && !isEmptyObj(computedDef)) { const computedUpdaters = (computedCache[curCacheId] = []); const threshold = Object.keys(computedDef).length; let sum = 0; const missDepend = {}; do { sum++; (isEmptyObj(missDepend) ? Object.keys(computedDef) : sort(missDepend)).forEach((field) => { const computedFunc = computedDef[field]; let relatedList = []; try { const val = computedFunc.call({ data: create(allData, relatedList) }); const missingDepend = relatedList.filter((item) => !(item.path[0] in allData)).map((ele) => ele.path[0]); if (missingDepend.length === 0) { dataDef[field] = allData[field] = unwrap(val); delete computedDef[field]; delete missDepend[field]; const updater = function () { let needUpdate = false; for (let i = 0; i < relatedList.length; i++) { const { path, value: oldVal } = relatedList[i]; const curVal = getDataOnPath(this.data, path); if (!equal(oldVal, curVal)) { needUpdate = true; break; } } if (!needUpdate) return false; const newRelatedList = []; const val = computedFunc.call({ data: create(this.data, newRelatedList) }); relatedList = newRelatedList; this.setData({ [field]: unwrap(val), }); return true; }; computedUpdaters.push(updater); } else { missDepend[field] = missingDepend; } } catch (error) { if (sum === threshold) { throw Error(`计算属性字段${field}中依赖的字段不存在,${sum}`); } } }); } while (!isEmptyObj(computedDef)); const observers = (options.observers || (options.observers = {})); const originOFunc = observers["**"]; observers["**"] = function () { const computedUpdaters = computedCache[curCacheId]; let changed; do { changed = computedUpdaters.some((updater) => updater.call(this)); } while (changed); originOFunc === null || originOFunc === void 0 ? void 0 : originOFunc.call(this); }; } const watchDef = options.watch; const observersItems = []; if (watchDef) { Object.keys(watchDef).forEach((watchPath) => { const pathList = parseMultiDataPaths(watchPath); const curValList = getCurWatchPathsVal(pathList, allData); watchCache[curCacheId] || (watchCache[curCacheId] = {}); watchCache[curCacheId][watchPath] = curValList; observersItems.push({ fields: watchPath, observer() { const oldVal = watchCache[curCacheId][watchPath]; const curVal = getCurWatchPathsVal(pathList, this.data); watchCache[curCacheId][watchPath] = curVal; let changed = false; for (let i = 0; i < curVal.length; i++) { const options = pathList[i].options; const deepCmp = options.deepCmp; if (deepCmp ? !deepEqual(oldVal[i], curVal[i]) : !equal(oldVal[i], curVal[i])) { changed = true; break; } } if (changed) { watchDef[watchPath].apply(this, [...curVal, ...oldVal]); } }, }); }); const observersDef = (options.observers || (options.observers = {})); observersItems.forEach((item) => { const f = observersDef[item.fields]; if (!f) { observersDef[item.fields] = item.observer; } else { observersDef[item.fields] = function () { item.observer.call(this); f.call(this); }; } }); } }, }); function getCurWatchPathsVal(paths, allData) { return paths.map(({ path, options }) => { const val = getDataOnPath(allData, path); return options.deepCmp ? deepClone(val) : val; }); } function equal(a, b) { if (a === b || JSON.stringify(a) === JSON.stringify(b)) { return true; } else { return a !== a && b !== b; } } //# sourceMappingURL=index.js.map