ewm
Version:
小程序原生插件
187 lines • 7.89 kB
JavaScript
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