修改了oakFilters和oakSorters参数的处理,以及cache在get时发现数据缺失时要不要去取missedRows的逻辑
This commit is contained in:
parent
a0a7018c9f
commit
a03ae917dc
|
|
@ -10,6 +10,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
|||
private aspectWrapper;
|
||||
private syncEventsCallbacks;
|
||||
private contextBuilder?;
|
||||
private refreshing;
|
||||
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD>, contextBuilder: () => FrontCxt, store: CacheStore<ED, FrontCxt>);
|
||||
getSchema(): import("oak-domain/lib/types").StorageSchema<ED>;
|
||||
getCurrentUserId(allowUnloggedIn?: boolean): string | undefined;
|
||||
|
|
@ -22,7 +23,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
|||
count: number | undefined;
|
||||
}>;
|
||||
aggregate<T extends keyof ED, OP extends SelectOption>(entity: T, aggregation: ED[T]['Aggregation'], option?: OP): Promise<import("oak-domain/lib/types").AggregationResult<ED[keyof ED]["Schema"]>>;
|
||||
operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], option?: OP, callback?: (result: Awaited<ReturnType<AD['operate']>>) => void): Promise<{
|
||||
operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'] | ED[T]['Operation'][], option?: OP, callback?: (result: Awaited<ReturnType<AD['operate']>>) => void): Promise<{
|
||||
result: Awaited<ReturnType<AD["operate"]>>;
|
||||
message: string | null | undefined;
|
||||
}>;
|
||||
|
|
@ -39,22 +40,12 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends A
|
|||
entity: T;
|
||||
})[]): true | Error;
|
||||
checkOperation<T extends keyof ED>(entity: T, action: ED[T]['Action'], data?: ED[T]['Update']['data'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]): boolean;
|
||||
/**
|
||||
* 尝试在cache中重做一些动作,然后选择重做后的数据(为了实现modi)
|
||||
* @param entity
|
||||
* @param selection
|
||||
* @param opers
|
||||
*/
|
||||
tryRedoOperationsThenSelect<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
}>, allowMiss?: boolean): Partial<ED[T]["Schema"]>[];
|
||||
redoOperation(opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
}>, context: FrontCxt): void;
|
||||
private getInner;
|
||||
get<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], allowMiss?: boolean, context?: FrontCxt): Partial<ED[T]["Schema"]>[];
|
||||
get<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context?: FrontCxt): Partial<ED[T]["Schema"]>[];
|
||||
judgeRelation(entity: keyof ED, attr: string): string | 0 | 1 | 2 | string[];
|
||||
bindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void;
|
||||
unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => void): void;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ var Cache = /** @class */ (function (_super) {
|
|||
tslib_1.__extends(Cache, _super);
|
||||
function Cache(aspectWrapper, contextBuilder, store) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this.refreshing = false;
|
||||
_this.aspectWrapper = aspectWrapper;
|
||||
_this.syncEventsCallbacks = [];
|
||||
_this.contextBuilder = contextBuilder;
|
||||
|
|
@ -74,14 +75,17 @@ var Cache = /** @class */ (function (_super) {
|
|||
var _a, ids, count, selection2, data;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0: return [4 /*yield*/, this.exec('select', {
|
||||
entity: entity,
|
||||
selection: selection,
|
||||
option: option,
|
||||
getCount: getCount,
|
||||
}, callback)];
|
||||
case 0:
|
||||
this.refreshing = true;
|
||||
return [4 /*yield*/, this.exec('select', {
|
||||
entity: entity,
|
||||
selection: selection,
|
||||
option: option,
|
||||
getCount: getCount,
|
||||
}, callback)];
|
||||
case 1:
|
||||
_a = (_b.sent()).result, ids = _a.ids, count = _a.count;
|
||||
this.refreshing = false;
|
||||
selection2 = Object.assign({}, selection, {
|
||||
filter: {
|
||||
id: {
|
||||
|
|
@ -117,14 +121,20 @@ var Cache = /** @class */ (function (_super) {
|
|||
};
|
||||
Cache.prototype.operate = function (entity, operation, option, callback) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var result;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.exec('operate', {
|
||||
entity: entity,
|
||||
operation: operation,
|
||||
option: option,
|
||||
}, callback)];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
case 0:
|
||||
this.refreshing = true;
|
||||
return [4 /*yield*/, this.exec('operate', {
|
||||
entity: entity,
|
||||
operation: operation,
|
||||
option: option,
|
||||
}, callback)];
|
||||
case 1:
|
||||
result = _a.sent();
|
||||
this.refreshing = false;
|
||||
return [2 /*return*/, result];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -209,45 +219,6 @@ var Cache = /** @class */ (function (_super) {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 尝试在cache中重做一些动作,然后选择重做后的数据(为了实现modi)
|
||||
* @param entity
|
||||
* @param selection
|
||||
* @param opers
|
||||
*/
|
||||
Cache.prototype.tryRedoOperationsThenSelect = function (entity, selection, opers, allowMiss) {
|
||||
var e_3, _a;
|
||||
var context = this.contextBuilder();
|
||||
context.begin();
|
||||
try {
|
||||
try {
|
||||
for (var opers_1 = tslib_1.__values(opers), opers_1_1 = opers_1.next(); !opers_1_1.done; opers_1_1 = opers_1.next()) {
|
||||
var oper = opers_1_1.value;
|
||||
this.cacheStore.operate(oper.entity, (0, lodash_1.cloneDeep)(oper.operation), context, {
|
||||
dontCollect: true,
|
||||
dontCreateOper: true,
|
||||
blockTrigger: true,
|
||||
dontCreateModi: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (opers_1_1 && !opers_1_1.done && (_a = opers_1.return)) _a.call(opers_1);
|
||||
}
|
||||
finally { if (e_3) throw e_3.error; }
|
||||
}
|
||||
// 这个场景下要把可能刚刚delete的行返回
|
||||
var result = this.getInner(entity, selection, context, allowMiss, true);
|
||||
context.rollback();
|
||||
return result;
|
||||
}
|
||||
catch (err) {
|
||||
context.rollback();
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
Cache.prototype.redoOperation = function (opers, context) {
|
||||
var _this = this;
|
||||
opers.forEach(function (oper) {
|
||||
|
|
@ -261,7 +232,7 @@ var Cache = /** @class */ (function (_super) {
|
|||
});
|
||||
return;
|
||||
};
|
||||
Cache.prototype.getInner = function (entity, selection, context, allowMiss, includedDeleted) {
|
||||
Cache.prototype.getInner = function (entity, selection, context, includedDeleted) {
|
||||
var _this = this;
|
||||
try {
|
||||
var result = this.cacheStore.select(entity, selection, context, {
|
||||
|
|
@ -272,11 +243,11 @@ var Cache = /** @class */ (function (_super) {
|
|||
}
|
||||
catch (err) {
|
||||
if (err instanceof Exception_1.OakRowUnexistedException) {
|
||||
if (!allowMiss) {
|
||||
if (!this.refreshing) {
|
||||
var missedRows_1 = err.getRows();
|
||||
this.exec('fetchRows', missedRows_1, function (result, opRecords) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||||
var _a, _b, record, d, missedRows_2, missedRows_2_1, mr;
|
||||
var e_4, _c, e_5, _d;
|
||||
var e_3, _c, e_4, _d;
|
||||
return tslib_1.__generator(this, function (_e) {
|
||||
try {
|
||||
// missedRows理论上一定要取到,不能为空集。否则就是程序员有遗漏
|
||||
|
|
@ -285,26 +256,26 @@ var Cache = /** @class */ (function (_super) {
|
|||
d = record.d;
|
||||
(0, assert_1.default)(Object.keys(d).length > 0, '在通过fetchRow取不一致数据时返回了空数据,请拿该程序员祭天。');
|
||||
try {
|
||||
for (missedRows_2 = (e_5 = void 0, tslib_1.__values(missedRows_1)), missedRows_2_1 = missedRows_2.next(); !missedRows_2_1.done; missedRows_2_1 = missedRows_2.next()) {
|
||||
for (missedRows_2 = (e_4 = void 0, tslib_1.__values(missedRows_1)), missedRows_2_1 = missedRows_2.next(); !missedRows_2_1.done; missedRows_2_1 = missedRows_2.next()) {
|
||||
mr = missedRows_2_1.value;
|
||||
(0, assert_1.default)(Object.keys(d[mr.entity]).length > 0, "\u5728\u901A\u8FC7fetchRow\u53D6\u4E0D\u4E00\u81F4\u6570\u636E\u65F6\u8FD4\u56DE\u4E86\u7A7A\u6570\u636E\uFF0C\u8BF7\u62FF\u8BE5\u7A0B\u5E8F\u5458\u796D\u5929\u3002entity\u662F".concat(mr.entity));
|
||||
}
|
||||
}
|
||||
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
||||
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (missedRows_2_1 && !missedRows_2_1.done && (_d = missedRows_2.return)) _d.call(missedRows_2);
|
||||
}
|
||||
finally { if (e_5) throw e_5.error; }
|
||||
finally { if (e_4) throw e_4.error; }
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
||||
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
||||
}
|
||||
finally { if (e_4) throw e_4.error; }
|
||||
finally { if (e_3) throw e_3.error; }
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
|
|
@ -317,9 +288,9 @@ var Cache = /** @class */ (function (_super) {
|
|||
}
|
||||
}
|
||||
};
|
||||
Cache.prototype.get = function (entity, selection, allowMiss, context) {
|
||||
Cache.prototype.get = function (entity, selection, context) {
|
||||
var context2 = context || this.contextBuilder();
|
||||
return this.getInner(entity, selection, context2, allowMiss);
|
||||
return this.getInner(entity, selection, context2);
|
||||
};
|
||||
Cache.prototype.judgeRelation = function (entity, attr) {
|
||||
return this.cacheStore.judgeRelation(entity, attr);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,6 @@ export declare type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T
|
|||
path: string;
|
||||
entity?: T;
|
||||
isList?: boolean;
|
||||
isPicker?: boolean;
|
||||
projection?: ED[T]['Selection']['data'] | (() => ED[T]['Selection']['data']);
|
||||
pagination?: Pagination;
|
||||
filters?: NamedFilterItem<ED, T>[];
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ var ListNode = /** @class */ (function (_super) {
|
|||
data: data,
|
||||
filter: filter,
|
||||
sorter: sorter,
|
||||
}, undefined, context);
|
||||
}, context);
|
||||
return result.filter(function (ele) { var _a; return ele.$$createAt$$ === 1 || ((_a = _this.ids) === null || _a === void 0 ? void 0 : _a.includes(ele.id)); });
|
||||
};
|
||||
ListNode.prototype.addItem = function (item, beforeExecute, afterExecute) {
|
||||
|
|
@ -1084,7 +1084,7 @@ var SingleNode = /** @class */ (function (_super) {
|
|||
filter: {
|
||||
id: id,
|
||||
},
|
||||
}, undefined, context);
|
||||
}, context);
|
||||
return result[0];
|
||||
}
|
||||
};
|
||||
|
|
@ -2081,12 +2081,9 @@ var RunningTree = /** @class */ (function (_super) {
|
|||
operations = node.composeOperations();
|
||||
entities = (0, lodash_1.uniq)(operations.filter(function (ele) { return !!ele; }).map(function (ele) { return ele.entity; }));
|
||||
(0, assert_1.assert)(entities.length === 1);
|
||||
return [4 /*yield*/, this.cache.exec('operate', {
|
||||
entity: entities[0],
|
||||
operation: operations
|
||||
.filter(function (ele) { return !!ele; })
|
||||
.map(function (ele) { return ele.operation; }),
|
||||
}, function () {
|
||||
return [4 /*yield*/, this.cache.operate(entities[0], operations
|
||||
.filter(function (ele) { return !!ele; })
|
||||
.map(function (ele) { return ele.operation; }), undefined, function () {
|
||||
// 清空缓存
|
||||
node.clean();
|
||||
node.setExecuting(false);
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ var relation_1 = require("oak-domain/lib/store/relation");
|
|||
var filter_1 = require("oak-domain/lib/store/filter");
|
||||
function onPathSet(option) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var _a, props, state, _b, oakPath, oakProjection, oakIsPicker, oakFilters, oakSorters, oakId, entity, path, projection, isList, filters, sorters, pagination, features, oakPath2, entity2_1, filters2, oakFilters2, _loop_1, filters_1, filters_1_1, ele, proj, sorters2, oakSorters2, _loop_2, sorters_1, sorters_1_1, ele, actions_1, cascadeActions_1;
|
||||
var _a, props, state, _b, oakPath, oakProjection, oakFilters, oakSorters, oakId, entity, path, projection, isList, filters, sorters, pagination, features, oakPath2, entity2_1, filters2, oakFilters2, _loop_1, filters_1, filters_1_1, ele, proj, sorters2, oakSorters2, _loop_2, sorters_1, sorters_1_1, ele, actions_1, cascadeActions_1;
|
||||
var e_1, _c, e_2, _d;
|
||||
var _this = this;
|
||||
return tslib_1.__generator(this, function (_e) {
|
||||
switch (_e.label) {
|
||||
case 0:
|
||||
_a = this, props = _a.props, state = _a.state;
|
||||
_b = props, oakPath = _b.oakPath, oakProjection = _b.oakProjection, oakIsPicker = _b.oakIsPicker, oakFilters = _b.oakFilters, oakSorters = _b.oakSorters, oakId = _b.oakId;
|
||||
_b = props, oakPath = _b.oakPath, oakProjection = _b.oakProjection, oakFilters = _b.oakFilters, oakSorters = _b.oakSorters, oakId = _b.oakId;
|
||||
entity = option.entity, path = option.path, projection = option.projection, isList = option.isList, filters = option.filters, sorters = option.sorters, pagination = option.pagination;
|
||||
features = this.features;
|
||||
oakPath2 = oakPath || path;
|
||||
|
|
@ -101,7 +101,6 @@ function onPathSet(option) {
|
|||
path: oakPath2,
|
||||
entity: entity2_1,
|
||||
isList: isList,
|
||||
isPicker: oakIsPicker,
|
||||
projection: proj,
|
||||
pagination: pagination,
|
||||
filters: filters2,
|
||||
|
|
@ -162,7 +161,7 @@ function checkActionsAndCascadeEntities(rows, option) {
|
|||
var e_3, _a;
|
||||
var _this = this;
|
||||
var checkTypes = ['relation', 'row', 'logical', 'logicalRelation'];
|
||||
var actions = this.props.oakActions || (typeof option.actions === 'function' ? option.actions.call(this) : option.actions);
|
||||
var actions = this.props.oakActions ? JSON.parse(this.props.oakActions) : (typeof option.actions === 'function' ? option.actions.call(this) : option.actions);
|
||||
var legalActions = [];
|
||||
if (actions) {
|
||||
var _loop_3 = function (action) {
|
||||
|
|
@ -244,7 +243,7 @@ function checkActionsAndCascadeEntities(rows, option) {
|
|||
finally { if (e_3) throw e_3.error; }
|
||||
}
|
||||
}
|
||||
var cascadeActionDict = this.props.oakCascadeActions || ((option.cascadeActions && option.cascadeActions.call(this)));
|
||||
var cascadeActionDict = this.props.oakCascadeActions ? JSON.parse(this.props.oakCascadeActions) : ((option.cascadeActions && option.cascadeActions.call(this)));
|
||||
if (cascadeActionDict) {
|
||||
var addToRow_1 = function (r, e, a) {
|
||||
var _a, _b;
|
||||
|
|
@ -396,12 +395,13 @@ function reRender(option, extra) {
|
|||
oakLegalActions: oakLegalActions,
|
||||
});
|
||||
if (option.isList) {
|
||||
var oakFilters = this.getFilters();
|
||||
var oakSorters = this.getSorters();
|
||||
// 因为oakFilters和props里的oakFilters同名,这里只能先注掉,好像还没有组件用过
|
||||
// const oakFilters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getFilters();
|
||||
// const oakSorters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getSorters();
|
||||
var oakPagination = this.getPagination();
|
||||
Object.assign(data, {
|
||||
oakFilters: oakFilters,
|
||||
oakSorters: oakSorters,
|
||||
// oakFilters,
|
||||
// oakSorters,
|
||||
oakPagination: oakPagination,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,22 +12,23 @@ var OakProperties = {
|
|||
oakPath: '',
|
||||
oakFilters: [],
|
||||
oakSorters: [],
|
||||
oakIsPicker: false,
|
||||
oakProjection: {},
|
||||
oakParentEntity: '',
|
||||
oakFrom: '',
|
||||
oakActions: [],
|
||||
oakActions: '',
|
||||
oakAutoUnmount: false,
|
||||
oakDisablePulldownRefresh: false,
|
||||
};
|
||||
var OakPropertyTypes = {
|
||||
oakId: String,
|
||||
oakPath: String,
|
||||
oakFilters: Array,
|
||||
oakSorters: Array,
|
||||
oakIsPicker: Boolean,
|
||||
// 这几个不能写成Array或Object,小程序会初始化成空对象和空数组
|
||||
oakFilters: null,
|
||||
oakSorters: null,
|
||||
oakProjection: null,
|
||||
oakParentEntity: String,
|
||||
oakFrom: String,
|
||||
oakActions: Array,
|
||||
oakActions: String,
|
||||
oakAutoUnmount: Boolean,
|
||||
oakDisablePulldownRefresh: Boolean,
|
||||
};
|
||||
|
|
@ -94,7 +95,7 @@ var oakBehavior = Behavior({
|
|||
dataResolved = {};
|
||||
assignProps = function (data, property, type) {
|
||||
var _a;
|
||||
if (data[property]) {
|
||||
if (data.hasOwnProperty(property)) {
|
||||
var value = data[property];
|
||||
if (typeof data[property] === 'string' && type !== 'string') {
|
||||
switch (type) {
|
||||
|
|
@ -120,23 +121,21 @@ var oakBehavior = Behavior({
|
|||
_a));
|
||||
}
|
||||
};
|
||||
/**
|
||||
* query是跳页面时从queryString里传值
|
||||
* this.data是properties中有定义的时候在会自动赋值,这里没必要再处理一遍
|
||||
*/
|
||||
if (properties) {
|
||||
for (key in properties) {
|
||||
if (query[key]) {
|
||||
assignProps(query, key, typeof properties[key]);
|
||||
}
|
||||
else if (this.data) {
|
||||
assignProps(this.data, key, typeof properties[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (key in OakProperties) {
|
||||
if (query[key]) {
|
||||
assignProps(query, key, typeof OakProperties[key]);
|
||||
}
|
||||
else if (this.data) {
|
||||
assignProps(this.data, key, typeof OakProperties[key]);
|
||||
}
|
||||
}
|
||||
if (Object.keys(dataResolved).length > 0) {
|
||||
this.setState(dataResolved);
|
||||
|
|
@ -238,6 +237,12 @@ var oakBehavior = Behavior({
|
|||
getId: function () {
|
||||
return this.features.runningTree.getId(this.state.oakFullpath);
|
||||
},
|
||||
setNamedFilters: function (filters, refresh, path) {
|
||||
var path2 = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedFilters(path2, filters, refresh);
|
||||
},
|
||||
setFilters: function (filters, path) {
|
||||
var path2 = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
|
|
@ -291,11 +296,11 @@ var oakBehavior = Behavior({
|
|||
: this.state.oakFullpath;
|
||||
this.features.runningTree.removeNamedFilterByName(path2, name, refresh);
|
||||
},
|
||||
setNamedSorters: function (namedSorters, path) {
|
||||
setNamedSorters: function (namedSorters, refresh, path) {
|
||||
var path2 = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters);
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters, refresh);
|
||||
},
|
||||
getSorters: function (path) {
|
||||
if (this.state.oakFullpath) {
|
||||
|
|
@ -448,6 +453,33 @@ var oakBehavior = Behavior({
|
|||
}
|
||||
}
|
||||
},
|
||||
/* oakFilters(data) {
|
||||
if (data !== this.props.oakFilters) {
|
||||
// 如果oakFilters被置空或重置,会完全重置当前结点上所有的nameFilter并重取数据。这个逻辑可能有问题,对oakFilters要慎用
|
||||
if (!data) {
|
||||
this.setNamedFilters([], true);
|
||||
}
|
||||
else {
|
||||
const namedFilters = JSON.parse(data);
|
||||
this.setNamedFilters(namedFilters, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
oakSorters(data) {
|
||||
if (data !== this.props.oakSorters) {
|
||||
// 如果oakSorters被置空或重置,会完全重置当前结点上所有的nameSorter并重取数据。这个逻辑可能有问题,对oakSorter要慎用
|
||||
if (!data) {
|
||||
this.setNamedSorters([], true);
|
||||
}
|
||||
else {
|
||||
const namedSorters = JSON.parse(data);
|
||||
this.setNamedSorters(namedSorters, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
oakProjection(data) {
|
||||
assert(data === this.props.oakProjection, 'oakProjection暂不支持变化');
|
||||
} */
|
||||
},
|
||||
pageLifetimes: {
|
||||
show: function () {
|
||||
|
|
|
|||
|
|
@ -239,6 +239,12 @@ var OakComponentBase = /** @class */ (function (_super) {
|
|||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedFilters(path2, filters);
|
||||
};
|
||||
OakComponentBase.prototype.setNamedFilters = function (filters, refresh, path) {
|
||||
var path2 = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedFilters(path2, filters, refresh);
|
||||
};
|
||||
OakComponentBase.prototype.getFilters = function (path) {
|
||||
if (this.state.oakFullpath) {
|
||||
var path2 = path
|
||||
|
|
@ -287,11 +293,11 @@ var OakComponentBase = /** @class */ (function (_super) {
|
|||
: this.state.oakFullpath;
|
||||
this.features.runningTree.removeNamedFilterByName(path2, name, refresh);
|
||||
};
|
||||
OakComponentBase.prototype.setNamedSorters = function (namedSorters, path) {
|
||||
OakComponentBase.prototype.setNamedSorters = function (namedSorters, refresh, path) {
|
||||
var path2 = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters);
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters, refresh);
|
||||
};
|
||||
OakComponentBase.prototype.getSorters = function (path) {
|
||||
if (this.state.oakFullpath) {
|
||||
|
|
@ -489,6 +495,9 @@ function createComponent(option, features) {
|
|||
setFilters: function (filters, path) {
|
||||
return _this.setFilters(filters, path);
|
||||
},
|
||||
setNamedFilters: function (filters, refresh, path) {
|
||||
return _this.setNamedFilters(filters, refresh, path);
|
||||
},
|
||||
addNamedFilter: function (filter, refresh, path) {
|
||||
return _this.addNamedFilter(filter, refresh, path);
|
||||
},
|
||||
|
|
@ -498,8 +507,8 @@ function createComponent(option, features) {
|
|||
removeNamedFilterByName: function (name, refresh, path) {
|
||||
return _this.removeNamedFilterByName(name, refresh, path);
|
||||
},
|
||||
setNamedSorters: function (sorters, path) {
|
||||
return _this.setNamedSorters(sorters, path);
|
||||
setNamedSorters: function (sorters, refresh, path) {
|
||||
return _this.setNamedSorters(sorters, refresh, path);
|
||||
},
|
||||
addNamedSorter: function (sorter, refresh, path) {
|
||||
return _this.addNamedSorter(sorter, refresh, path);
|
||||
|
|
@ -640,7 +649,6 @@ function createComponent(option, features) {
|
|||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.show) && lifetimes.show.call(this);
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
// 这个if看不太懂,先注掉,不确定有无问题。by Xc 20230322
|
||||
if (!option.entity) {
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.ready) && lifetimes.ready.call(this);
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.show) && lifetimes.show.call(this);
|
||||
|
|
@ -681,7 +689,29 @@ function createComponent(option, features) {
|
|||
(0, assert_1.default)(this.props.oakId); // 好像不可能把已有的id设空的界面需求吧
|
||||
this.setId(this.props.oakId);
|
||||
}
|
||||
// todo 这里似乎还可能对oakProjection这些东西加以更新,等遇到再添加 by Xc
|
||||
/* 这几个东西暂不支持变化,必须在初始化时确定
|
||||
// 如果上层将oakFilters和oakSorters作为props传入,这里会将当前的filters和sorters清空,所以使用这两个props时最好是静态不变的
|
||||
if (this.props.oakFilters !== prevProps.oakFilters) {
|
||||
if (this.props.oakFilters) {
|
||||
const namedFilters = JSON.parse(this.props.oakFilters!);
|
||||
this.setNamedFilters(namedFilters, true);
|
||||
}
|
||||
else {
|
||||
this.setNamedFilters([], true);
|
||||
}
|
||||
}
|
||||
if (this.props.oakSorters !== prevProps.oakSorters) {
|
||||
if (this.props.oakSorters) {
|
||||
const namedSorters = JSON.parse(this.props.oakSorters!);
|
||||
this.setNamedSorters(namedSorters, true);
|
||||
}
|
||||
else {
|
||||
this.setNamedSorters([], true);
|
||||
}
|
||||
}
|
||||
if (this.props.oakProjection !== prevProps.oakProjection) {
|
||||
assert(false, 'oakProjection参数暂不允许变动');
|
||||
} */
|
||||
fn && fn.call(this, prevProps, prevState);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
import React from 'react';
|
||||
declare const withRouter: (Component: React.ComponentType<any>, { path, properties }: {
|
||||
path?: string | undefined;
|
||||
properties?: Record<string, FunctionConstructor | WechatMiniprogram.Component.AllProperty> | undefined;
|
||||
properties?: Record<string, any> | undefined;
|
||||
}) => React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
|
||||
export default withRouter;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ var react_router_dom_1 = require("react-router-dom");
|
|||
var react_i18next_1 = require("react-i18next");
|
||||
var responsive_1 = require("./../responsive");
|
||||
var url_1 = tslib_1.__importDefault(require("url"));
|
||||
var console_1 = require("console");
|
||||
function getParams(location, properties) {
|
||||
var search = location.search, state = location.state;
|
||||
var query = getQuery(search, properties);
|
||||
|
|
@ -25,28 +26,27 @@ function getQuery(url, properties) {
|
|||
var query2 = {};
|
||||
for (var k in query) {
|
||||
if (properties && properties[k]) {
|
||||
var type = typeof properties[k] === 'function' ? properties[k] : properties[k].type;
|
||||
switch (type) {
|
||||
case Number: {
|
||||
switch (typeof properties[k]) {
|
||||
case 'number': {
|
||||
Object.assign(query2, (_a = {},
|
||||
_a[k] = Number(query[k]),
|
||||
_a));
|
||||
break;
|
||||
}
|
||||
case Boolean: {
|
||||
case 'boolean': {
|
||||
Object.assign(query2, (_b = {},
|
||||
_b[k] = Boolean(query[k]),
|
||||
_b));
|
||||
break;
|
||||
}
|
||||
case Array:
|
||||
case Object: {
|
||||
case 'object': {
|
||||
Object.assign(query2, (_c = {},
|
||||
_c[k] = JSON.parse(query[k]),
|
||||
_c));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
(0, console_1.assert)(typeof properties[k] === 'string', '传参只能是number/boolean/object/string四种类型');
|
||||
Object.assign(query2, (_d = {},
|
||||
_d[k] = query[k],
|
||||
_d));
|
||||
|
|
@ -55,19 +55,20 @@ function getQuery(url, properties) {
|
|||
}
|
||||
else {
|
||||
switch (k) {
|
||||
case 'oakIsPicker':
|
||||
case 'oakDisablePulldownRefresh': {
|
||||
Object.assign(query2, (_e = {},
|
||||
_e[k] = Boolean(query[k]),
|
||||
_e));
|
||||
break;
|
||||
}
|
||||
case 'oakFilters':
|
||||
case 'oakSorters': {
|
||||
case 'oakProjection':
|
||||
case 'oakSorters':
|
||||
case 'oakFilters': {
|
||||
Object.assign(query2, (_f = {},
|
||||
_f[k] = JSON.parse(query[k]),
|
||||
_f));
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Object.assign(query2, (_g = {},
|
||||
|
|
|
|||
|
|
@ -109,21 +109,17 @@ export declare type OakComponentOption<ED extends EntityDict & BaseEntityDict, T
|
|||
export declare type OakComponentProperties<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = Partial<{
|
||||
oakPath: string;
|
||||
oakId: string;
|
||||
oakProjection: ED[T]['Selection']['data'];
|
||||
oakFrom: string;
|
||||
oakParentEntity: string;
|
||||
oakDisablePulldownRefresh: boolean;
|
||||
oakAutoUnmount: boolean;
|
||||
oakActions: ED[T]['Action'][];
|
||||
oakCascadeActions: {
|
||||
[K in keyof ED[T]['Schema']]?: ActionDef<ED, keyof ED>[];
|
||||
};
|
||||
oakActions: string;
|
||||
oakCascadeActions: string;
|
||||
}>;
|
||||
export declare type OakListComponentProperties<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = Partial<{
|
||||
oakFilters: NamedFilterItem<ED, T>[];
|
||||
oakSorters: NamedSorterItem<ED, T>[];
|
||||
oakIsPicker: boolean;
|
||||
oakPagination: Pagination;
|
||||
oakProjection: ED[T]['Selection']['data'];
|
||||
}>;
|
||||
export declare type OakNavigateToParameters<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
oakId?: string;
|
||||
|
|
@ -133,7 +129,6 @@ export declare type OakNavigateToParameters<ED extends EntityDict & BaseEntityDi
|
|||
oakProjection?: ED[T]['Selection']['data'];
|
||||
oakSorters?: Array<NamedSorterItem<ED, T>>;
|
||||
oakFilters?: Array<NamedFilterItem<ED, T>>;
|
||||
oakIsPicker?: boolean;
|
||||
[k: string]: any;
|
||||
};
|
||||
export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
|
|
@ -189,9 +184,10 @@ export declare type OakListComponentMethods<ED extends EntityDict & BaseEntityDi
|
|||
getFilters: (path?: string) => ED[T]['Selection']['filter'][] | undefined;
|
||||
getFilterByName: (name: string, path?: string) => ED[T]['Selection']['filter'] | undefined;
|
||||
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
setNamedFilters: (filters: NamedFilterItem<ED, T>[], refresh?: boolean, path?: string) => void;
|
||||
removeNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
removeNamedFilterByName: (name: string, refresh?: boolean, path?: string) => void;
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], path?: string) => void;
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], refresh?: boolean, path?: string) => void;
|
||||
getSorters: (path?: string) => ED[T]['Selection']['sorter'] | undefined;
|
||||
getSorterByName: (name: string, path?: string) => NonNullable<ED[T]['Selection']['sorter']>[number] | undefined;
|
||||
addNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
|
|
@ -232,8 +228,6 @@ export declare type OakComponentData<ED extends EntityDict & BaseEntityDict, T e
|
|||
oakDisablePulldownRefresh: boolean;
|
||||
};
|
||||
declare type OakListComoponetData<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
oakFilters?: NonNullable<ED[T]['Selection']['filter']>[];
|
||||
oakSorters?: NonNullable<ED[T]['Selection']['sorter']>[];
|
||||
oakPagination?: Pagination;
|
||||
};
|
||||
export declare type MakeOakComponent<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature>> = <T extends keyof ED, FormedData extends DataOption, IsList extends boolean, TData extends DataOption, TProperty extends DataOption, TMethod extends MethodOption>(options: OakComponentOption<ED, T, Cxt, FrontCxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod>) => (props: ReactComponentProps<ED, T, IsList, TProperty>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export class Cache<
|
|||
(opRecords: OpRecord<ED>[]) => void
|
||||
>;
|
||||
private contextBuilder?: () => FrontCxt;
|
||||
private refreshing = false;
|
||||
|
||||
constructor(
|
||||
aspectWrapper: AspectWrapper<ED, Cxt, AD>,
|
||||
|
|
@ -93,12 +94,14 @@ export class Cache<
|
|||
getCount?: true,
|
||||
callback?: (result: Awaited<ReturnType<AD['select']>>) => void,
|
||||
) {
|
||||
this.refreshing = true;
|
||||
const { result: { ids, count } } = await this.exec('select', {
|
||||
entity,
|
||||
selection,
|
||||
option,
|
||||
getCount,
|
||||
}, callback);
|
||||
this.refreshing = false;
|
||||
|
||||
const selection2 = Object.assign({}, selection, {
|
||||
filter: {
|
||||
|
|
@ -130,15 +133,18 @@ export class Cache<
|
|||
|
||||
async operate<T extends keyof ED, OP extends OperateOption>(
|
||||
entity: T,
|
||||
operation: ED[T]['Operation'],
|
||||
operation: ED[T]['Operation'] | ED[T]['Operation'][],
|
||||
option?: OP,
|
||||
callback?: (result: Awaited<ReturnType<AD['operate']>>) => void,
|
||||
) {
|
||||
return await this.exec('operate', {
|
||||
this.refreshing = true;
|
||||
const result = await this.exec('operate', {
|
||||
entity,
|
||||
operation,
|
||||
option,
|
||||
}, callback);
|
||||
this.refreshing = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
async count<T extends keyof ED, OP extends SelectOption>(
|
||||
|
|
@ -211,49 +217,6 @@ export class Cache<
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试在cache中重做一些动作,然后选择重做后的数据(为了实现modi)
|
||||
* @param entity
|
||||
* @param selection
|
||||
* @param opers
|
||||
*/
|
||||
tryRedoOperationsThenSelect<T extends keyof ED>(
|
||||
entity: T,
|
||||
selection: ED[T]['Selection'],
|
||||
opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
}>,
|
||||
allowMiss?: boolean
|
||||
) {
|
||||
const context = this.contextBuilder!();
|
||||
context.begin();
|
||||
try {
|
||||
for (const oper of opers) {
|
||||
this.cacheStore!.operate(
|
||||
oper.entity,
|
||||
cloneDeep(oper.operation),
|
||||
context,
|
||||
{
|
||||
dontCollect: true,
|
||||
dontCreateOper: true,
|
||||
blockTrigger: true,
|
||||
dontCreateModi: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 这个场景下要把可能刚刚delete的行返回
|
||||
const result = this.getInner(entity, selection, context, allowMiss, true);
|
||||
context.rollback();
|
||||
return result;
|
||||
}
|
||||
catch (err) {
|
||||
context.rollback();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
redoOperation(opers: Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
@ -272,7 +235,7 @@ export class Cache<
|
|||
return;
|
||||
}
|
||||
|
||||
private getInner<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, allowMiss?: boolean, includedDeleted?: boolean): Partial<ED[T]['Schema']>[] {
|
||||
private getInner<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: SyncContext<ED>, includedDeleted?: boolean): Partial<ED[T]['Schema']>[] {
|
||||
try {
|
||||
const result = this.cacheStore!.select(
|
||||
entity,
|
||||
|
|
@ -286,7 +249,7 @@ export class Cache<
|
|||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof OakRowUnexistedException) {
|
||||
if (!allowMiss) {
|
||||
if (!this.refreshing) {
|
||||
const missedRows = err.getRows();
|
||||
this.exec('fetchRows', missedRows, async (result, opRecords) => {
|
||||
// missedRows理论上一定要取到,不能为空集。否则就是程序员有遗漏
|
||||
|
|
@ -309,12 +272,11 @@ export class Cache<
|
|||
get<T extends keyof ED>(
|
||||
entity: T,
|
||||
selection: ED[T]['Selection'],
|
||||
allowMiss?: boolean,
|
||||
context?: FrontCxt,
|
||||
) {
|
||||
const context2 = context || this.contextBuilder!();
|
||||
|
||||
return this.getInner(entity, selection, context2, allowMiss);
|
||||
return this.getInner(entity, selection, context2);
|
||||
}
|
||||
|
||||
judgeRelation(entity: keyof ED, attr: string) {
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ class ListNode<
|
|||
Cxt extends AsyncContext<ED>,
|
||||
FrontCxt extends SyncContext<ED>,
|
||||
AD extends CommonAspectDict<ED, Cxt>
|
||||
> extends Node<ED, T, Cxt, FrontCxt, AD> {
|
||||
> extends Node<ED, T, Cxt, FrontCxt, AD> {
|
||||
private children: Record<string, SingleNode<ED, T, Cxt, FrontCxt, AD>>;
|
||||
private updates: Record<
|
||||
string,
|
||||
|
|
@ -702,10 +702,10 @@ class ListNode<
|
|||
data,
|
||||
filter,
|
||||
sorter,
|
||||
}, undefined, context);
|
||||
}, context);
|
||||
return result.filter(
|
||||
ele => ele.$$createAt$$ === 1 || this.ids?.includes(ele.id!)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
addItem(
|
||||
|
|
@ -952,12 +952,12 @@ class ListNode<
|
|||
const sorterArr = sorters.filter(
|
||||
ele => !ignoreUnapplied || ele.applied
|
||||
).map((ele) => {
|
||||
const { sorter } = ele;
|
||||
if (typeof sorter === 'function') {
|
||||
return (sorter as Function)();
|
||||
}
|
||||
return sorter;
|
||||
})
|
||||
const { sorter } = ele;
|
||||
if (typeof sorter === 'function') {
|
||||
return (sorter as Function)();
|
||||
}
|
||||
return sorter;
|
||||
})
|
||||
.filter((ele) => !!ele) as ED[T]['Selection']['sorter'];
|
||||
|
||||
const filters = this.constructFilters(context, withParent, ignoreUnapplied);
|
||||
|
|
@ -1197,7 +1197,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
filter: {
|
||||
id,
|
||||
},
|
||||
}, undefined, context);
|
||||
}, context);
|
||||
return result[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -1422,19 +1422,19 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
const { data: [value] } = await this.cache.refresh(this.entity, {
|
||||
data: projection,
|
||||
filter,
|
||||
}, undefined, undefined, () => {
|
||||
}, undefined, undefined, () => {
|
||||
// 刷新后所有的更新都应当被丢弃(子层上可能会自动建立了this.create动作) 这里可能会有问题 by Xc 20230329
|
||||
this.setFiltersAndSortedApplied();
|
||||
this.setLoading(false);
|
||||
this.clean();
|
||||
});
|
||||
// 对于modi对象,在此缓存modiIds
|
||||
if (this.schema[this.entity].toModi && value) {
|
||||
// 对于modi对象,在此缓存modiIds
|
||||
if (this.schema[this.entity].toModi && value) {
|
||||
const { modi$entity } = value;
|
||||
this.modiIds = (modi$entity as Array<BaseEntityDict['modi']['OpSchema']>).map(ele => ele.id);
|
||||
this.publish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (err) {
|
||||
this.setLoading(false);
|
||||
|
|
@ -1581,7 +1581,7 @@ class VirtualNode<
|
|||
Cxt extends AsyncContext<ED>,
|
||||
FrontCxt extends SyncContext<ED>,
|
||||
AD extends CommonAspectDict<ED, Cxt>
|
||||
> extends Feature {
|
||||
> extends Feature {
|
||||
private dirty: boolean;
|
||||
private executing: boolean;
|
||||
private children: Record<string, SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD> | VirtualNode<ED, Cxt, FrontCxt, AD>>;
|
||||
|
|
@ -1729,7 +1729,6 @@ export type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends
|
|||
path: string;
|
||||
entity?: T;
|
||||
isList?: boolean;
|
||||
isPicker?: boolean;
|
||||
projection?: ED[T]['Selection']['data'] | (() => ED[T]['Selection']['data']);
|
||||
pagination?: Pagination;
|
||||
filters?: NamedFilterItem<ED, T>[];
|
||||
|
|
@ -1763,7 +1762,7 @@ export class RunningTree<
|
|||
Cxt extends AsyncContext<ED>,
|
||||
FrontCxt extends SyncContext<ED>,
|
||||
AD extends CommonAspectDict<ED, Cxt>
|
||||
> extends Feature {
|
||||
> extends Feature {
|
||||
private cache: Cache<ED, Cxt, FrontCxt, AD>;
|
||||
private schema: StorageSchema<ED>;
|
||||
private authDict: AuthDefDict<ED>;
|
||||
|
|
@ -2259,14 +2258,12 @@ export class RunningTree<
|
|||
);
|
||||
assert(entities.length === 1);
|
||||
|
||||
const result = await this.cache.exec(
|
||||
'operate',
|
||||
{
|
||||
entity: entities[0],
|
||||
operation: operations
|
||||
.filter((ele) => !!ele)
|
||||
.map((ele) => ele.operation),
|
||||
},
|
||||
const result = await this.cache.operate(
|
||||
entities[0],
|
||||
operations
|
||||
.filter((ele) => !!ele)
|
||||
.map((ele) => ele.operation),
|
||||
undefined,
|
||||
() => {
|
||||
// 清空缓存
|
||||
node.clean();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export async function onPathSet<
|
|||
this: ComponentFullThisType<ED, T, any, Cxt, FrontCxt>,
|
||||
option: OakComponentOption<ED, T, Cxt, FrontCxt, any, any, any, any, {}, {}, {}>) {
|
||||
const { props, state } = this;
|
||||
const { oakPath, oakProjection, oakIsPicker, oakFilters, oakSorters, oakId } = props as ComponentProps<ED, T, true, {}>;
|
||||
const { oakPath, oakProjection, oakFilters, oakSorters, oakId } = props as ComponentProps<ED, T, true, {}>;
|
||||
const { entity, path, projection, isList, filters, sorters, pagination } = option;
|
||||
const { features } = this;
|
||||
|
||||
|
|
@ -91,7 +91,6 @@ export async function onPathSet<
|
|||
path: oakPath2,
|
||||
entity: entity2,
|
||||
isList,
|
||||
isPicker: oakIsPicker,
|
||||
projection: proj,
|
||||
pagination: pagination,
|
||||
filters: filters2,
|
||||
|
|
@ -164,7 +163,7 @@ function checkActionsAndCascadeEntities<
|
|||
option: OakComponentOption<ED, T, Cxt, FrontCxt, any, any, any, any, {}, {}, {}>
|
||||
) {
|
||||
const checkTypes = ['relation', 'row', 'logical', 'logicalRelation'] as CheckerType[];
|
||||
const actions = this.props.oakActions || (typeof option.actions === 'function' ? option.actions.call(this) : option.actions);
|
||||
const actions = this.props.oakActions ? JSON.parse(this.props.oakActions) as ED[T]['Action'][] : (typeof option.actions === 'function' ? option.actions.call(this) : option.actions);
|
||||
const legalActions = [] as ActionDef<ED, T>[];
|
||||
if (actions) {
|
||||
// todo 这里actions整体进行测试的性能应该要高于一个个去测试
|
||||
|
|
@ -238,7 +237,7 @@ function checkActionsAndCascadeEntities<
|
|||
}
|
||||
const cascadeActionDict: {
|
||||
[K in keyof ED[T]['Schema']]?: ActionDef<ED, keyof ED>[];
|
||||
} = this.props.oakCascadeActions as any || ((option.cascadeActions && option.cascadeActions.call(this)));
|
||||
} = this.props.oakCascadeActions ? JSON.parse(this.props.oakCascadeActions) : ((option.cascadeActions && option.cascadeActions.call(this)));
|
||||
|
||||
if (cascadeActionDict) {
|
||||
const addToRow = (r: Partial<ED[keyof ED]['Schema']>, e: keyof ED[T]['Schema'], a: ActionDef<ED, keyof ED>) => {
|
||||
|
|
@ -392,12 +391,13 @@ export function reRender<
|
|||
});
|
||||
|
||||
if (option.isList) {
|
||||
const oakFilters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getFilters();
|
||||
const oakSorters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getSorters();
|
||||
// 因为oakFilters和props里的oakFilters同名,这里只能先注掉,好像还没有组件用过
|
||||
// const oakFilters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getFilters();
|
||||
// const oakSorters = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getSorters();
|
||||
const oakPagination = (this as ComponentFullThisType<ED, T, true, Cxt, FrontCxt>).getPagination();
|
||||
Object.assign(data, {
|
||||
oakFilters,
|
||||
oakSorters,
|
||||
// oakFilters,
|
||||
// oakSorters,
|
||||
oakPagination,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ const OakProperties = {
|
|||
oakPath: '',
|
||||
oakFilters: [],
|
||||
oakSorters: [],
|
||||
oakIsPicker: false,
|
||||
oakProjection: {},
|
||||
oakParentEntity: '',
|
||||
oakFrom: '',
|
||||
oakActions: [],
|
||||
oakActions: '',
|
||||
oakAutoUnmount: false,
|
||||
oakDisablePulldownRefresh: false,
|
||||
};
|
||||
|
|
@ -44,12 +44,13 @@ const OakProperties = {
|
|||
const OakPropertyTypes = {
|
||||
oakId: String,
|
||||
oakPath: String,
|
||||
oakFilters: Array,
|
||||
oakSorters: Array,
|
||||
oakIsPicker: Boolean,
|
||||
// 这几个不能写成Array或Object,小程序会初始化成空对象和空数组
|
||||
oakFilters: null,
|
||||
oakSorters: null,
|
||||
oakProjection: null,
|
||||
oakParentEntity: String,
|
||||
oakFrom: String,
|
||||
oakActions: Array,
|
||||
oakActions: String,
|
||||
oakAutoUnmount: Boolean,
|
||||
oakDisablePulldownRefresh: Boolean,
|
||||
}
|
||||
|
|
@ -80,7 +81,7 @@ const oakBehavior = Behavior<
|
|||
oakPath?: string;
|
||||
oakFilters?: string;
|
||||
oakSorters?: string;
|
||||
oakIsPicker?: boolean;
|
||||
oakProjection?: string;
|
||||
oakParentEntity?: string;
|
||||
oakFrom?: string;
|
||||
oakActions?: string;
|
||||
|
|
@ -179,7 +180,7 @@ const oakBehavior = Behavior<
|
|||
property: string,
|
||||
type: 'string' | 'boolean' | 'number' | 'object'
|
||||
) => {
|
||||
if (data[property]) {
|
||||
if (data.hasOwnProperty(property)) {
|
||||
let value = data[property];
|
||||
if (typeof data[property] === 'string' && type !== 'string') {
|
||||
switch (type) {
|
||||
|
|
@ -205,12 +206,14 @@ const oakBehavior = Behavior<
|
|||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* query是跳页面时从queryString里传值
|
||||
* this.data是properties中有定义的时候在会自动赋值,这里没必要再处理一遍
|
||||
*/
|
||||
if (properties) {
|
||||
for (const key in properties) {
|
||||
if (query[key]) {
|
||||
assignProps(query, key, typeof properties[key] as 'string');
|
||||
} else if (this.data) {
|
||||
assignProps(this.data, key, typeof properties[key] as 'string');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,12 +224,6 @@ const oakBehavior = Behavior<
|
|||
key,
|
||||
typeof OakProperties[key as keyof typeof OakProperties] as 'string'
|
||||
);
|
||||
} else if (this.data) {
|
||||
assignProps(
|
||||
this.data,
|
||||
key,
|
||||
typeof OakProperties[key as keyof typeof OakProperties] as 'string'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,6 +351,13 @@ const oakBehavior = Behavior<
|
|||
return this.features.runningTree.getId(this.state.oakFullpath);
|
||||
},
|
||||
|
||||
setNamedFilters(filters, refresh, path) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedFilters(path2, filters, refresh);
|
||||
},
|
||||
|
||||
setFilters(filters, path) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
|
|
@ -429,11 +433,11 @@ const oakBehavior = Behavior<
|
|||
);
|
||||
},
|
||||
|
||||
setNamedSorters(namedSorters, path) {
|
||||
setNamedSorters(namedSorters, refresh, path) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters);
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters, refresh);
|
||||
},
|
||||
|
||||
getSorters(path) {
|
||||
|
|
@ -644,6 +648,33 @@ const oakBehavior = Behavior<
|
|||
}
|
||||
}
|
||||
},
|
||||
/* oakFilters(data) {
|
||||
if (data !== this.props.oakFilters) {
|
||||
// 如果oakFilters被置空或重置,会完全重置当前结点上所有的nameFilter并重取数据。这个逻辑可能有问题,对oakFilters要慎用
|
||||
if (!data) {
|
||||
this.setNamedFilters([], true);
|
||||
}
|
||||
else {
|
||||
const namedFilters = JSON.parse(data);
|
||||
this.setNamedFilters(namedFilters, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
oakSorters(data) {
|
||||
if (data !== this.props.oakSorters) {
|
||||
// 如果oakSorters被置空或重置,会完全重置当前结点上所有的nameSorter并重取数据。这个逻辑可能有问题,对oakSorter要慎用
|
||||
if (!data) {
|
||||
this.setNamedSorters([], true);
|
||||
}
|
||||
else {
|
||||
const namedSorters = JSON.parse(data);
|
||||
this.setNamedSorters(namedSorters, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
oakProjection(data) {
|
||||
assert(data === this.props.oakProjection, 'oakProjection暂不支持变化');
|
||||
} */
|
||||
},
|
||||
pageLifetimes: {
|
||||
show() {
|
||||
|
|
@ -831,7 +862,7 @@ export function createComponent<
|
|||
oakPath: string;
|
||||
oakFilters: string;
|
||||
oakSorters: string;
|
||||
oakIsPicker: boolean;
|
||||
oakProjection?: string;
|
||||
oakParentEntity: string;
|
||||
oakFrom: string;
|
||||
oakActions: string;
|
||||
|
|
|
|||
|
|
@ -430,6 +430,13 @@ abstract class OakComponentBase<
|
|||
this.features.runningTree.setNamedFilters(path2, filters);
|
||||
}
|
||||
|
||||
setNamedFilters(filters: NamedFilterItem<ED, T>[], refresh?: boolean, path?: string) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedFilters(path2, filters, refresh);
|
||||
}
|
||||
|
||||
getFilters(path?: string) {
|
||||
if (this.state.oakFullpath) {
|
||||
const path2 = path
|
||||
|
|
@ -498,11 +505,11 @@ abstract class OakComponentBase<
|
|||
this.features.runningTree.removeNamedFilterByName(path2, name, refresh);
|
||||
}
|
||||
|
||||
setNamedSorters(namedSorters: NamedSorterItem<ED, T>[], path?: string) {
|
||||
setNamedSorters(namedSorters: NamedSorterItem<ED, T>[], refresh?: boolean, path?: string) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters);
|
||||
this.features.runningTree.setNamedSorters(path2, namedSorters, refresh);
|
||||
}
|
||||
|
||||
getSorters(path?: string) {
|
||||
|
|
@ -775,6 +782,9 @@ export function createComponent<
|
|||
setFilters: (filters: NamedFilterItem<ED, T>[], path?: string) => {
|
||||
return this.setFilters(filters, path);
|
||||
},
|
||||
setNamedFilters: (filters: NamedFilterItem<ED, T>[], refresh?: boolean, path?: string) => {
|
||||
return this.setNamedFilters(filters, refresh, path);
|
||||
},
|
||||
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean, path?: string) => {
|
||||
return this.addNamedFilter(filter, refresh, path);
|
||||
},
|
||||
|
|
@ -784,8 +794,8 @@ export function createComponent<
|
|||
removeNamedFilterByName: (name: string, refresh?: boolean, path?: string) => {
|
||||
return this.removeNamedFilterByName(name, refresh, path);
|
||||
},
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], path?: string) => {
|
||||
return this.setNamedSorters(sorters, path);
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], refresh?: boolean, path?: string) => {
|
||||
return this.setNamedSorters(sorters, refresh, path);
|
||||
},
|
||||
addNamedSorter: (sorter: NamedSorterItem<ED, T>, refresh?: boolean, path?: string) => {
|
||||
return this.addNamedSorter(sorter, refresh, path);
|
||||
|
|
@ -921,7 +931,6 @@ export function createComponent<
|
|||
lifetimes?.show && lifetimes.show.call(this);
|
||||
}
|
||||
else {
|
||||
// 这个if看不太懂,先注掉,不确定有无问题。by Xc 20230322
|
||||
if (!option.entity) {
|
||||
lifetimes?.ready && lifetimes.ready.call(this);
|
||||
lifetimes?.show && lifetimes.show.call(this);
|
||||
|
|
@ -961,7 +970,30 @@ export function createComponent<
|
|||
assert(this.props.oakId); // 好像不可能把已有的id设空的界面需求吧
|
||||
this.setId(this.props.oakId!);
|
||||
}
|
||||
// todo 这里似乎还可能对oakProjection这些东西加以更新,等遇到再添加 by Xc
|
||||
|
||||
/* 这几个东西暂不支持变化,必须在初始化时确定
|
||||
// 如果上层将oakFilters和oakSorters作为props传入,这里会将当前的filters和sorters清空,所以使用这两个props时最好是静态不变的
|
||||
if (this.props.oakFilters !== prevProps.oakFilters) {
|
||||
if (this.props.oakFilters) {
|
||||
const namedFilters = JSON.parse(this.props.oakFilters!);
|
||||
this.setNamedFilters(namedFilters, true);
|
||||
}
|
||||
else {
|
||||
this.setNamedFilters([], true);
|
||||
}
|
||||
}
|
||||
if (this.props.oakSorters !== prevProps.oakSorters) {
|
||||
if (this.props.oakSorters) {
|
||||
const namedSorters = JSON.parse(this.props.oakSorters!);
|
||||
this.setNamedSorters(namedSorters, true);
|
||||
}
|
||||
else {
|
||||
this.setNamedSorters([], true);
|
||||
}
|
||||
}
|
||||
if (this.props.oakProjection !== prevProps.oakProjection) {
|
||||
assert(false, 'oakProjection参数暂不允许变动');
|
||||
} */
|
||||
|
||||
fn && fn.call(this, prevProps, prevState);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,18 @@ import { useTranslation } from 'react-i18next';
|
|||
import { useWidth } from './../responsive';
|
||||
|
||||
import URL from 'url';
|
||||
import { assert } from 'console';
|
||||
|
||||
type Location = { state: Record<string, any>; search: string };
|
||||
|
||||
function getParams(location: Location, properties?: Record<string, FunctionConstructor | WechatMiniprogram.Component.AllProperty>) {
|
||||
function getParams(location: Location, properties?: Record<string, any>) {
|
||||
const { search, state } = location;
|
||||
const query = getQuery(search, properties);
|
||||
|
||||
return Object.assign({}, query, state);
|
||||
}
|
||||
|
||||
function getQuery(url: string, properties?: Record<string, FunctionConstructor | WechatMiniprogram.Component.AllProperty>) {
|
||||
function getQuery(url: string, properties?: Record<string, any>) {
|
||||
let query: Record<string, any> = {};
|
||||
if (!url) {
|
||||
return query;
|
||||
|
|
@ -25,31 +26,30 @@ function getQuery(url: string, properties?: Record<string, FunctionConstructor |
|
|||
query = parseUrl.query;
|
||||
}
|
||||
const query2 = {};
|
||||
|
||||
|
||||
for (const k in query) {
|
||||
if (properties && properties[k]) {
|
||||
const type = typeof properties[k] === 'function' ? properties[k] : (properties[k] as any).type;
|
||||
switch (type) {
|
||||
case Number: {
|
||||
switch (typeof properties[k]) {
|
||||
case 'number': {
|
||||
Object.assign(query2, {
|
||||
[k]: Number(query[k]),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case Boolean: {
|
||||
case 'boolean': {
|
||||
Object.assign(query2, {
|
||||
[k]: Boolean(query[k]),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case Array:
|
||||
case Object: {
|
||||
case 'object': {
|
||||
Object.assign(query2, {
|
||||
[k]: JSON.parse(query[k]),
|
||||
});
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert(typeof properties[k] === 'string', '传参只能是number/boolean/object/string四种类型');
|
||||
Object.assign(query2, {
|
||||
[k]: query[k],
|
||||
})
|
||||
|
|
@ -58,20 +58,20 @@ function getQuery(url: string, properties?: Record<string, FunctionConstructor |
|
|||
}
|
||||
else {
|
||||
switch (k) {
|
||||
case 'oakIsPicker':
|
||||
case 'oakDisablePulldownRefresh': {
|
||||
Object.assign(query2, {
|
||||
[k]: Boolean(query[k]),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'oakFilters':
|
||||
case 'oakSorters': {
|
||||
case 'oakProjection':
|
||||
case 'oakSorters':
|
||||
case 'oakFilters': {
|
||||
Object.assign(query2, {
|
||||
[k]: JSON.parse(query[k]),
|
||||
});
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Object.assign(query2, {
|
||||
|
|
@ -84,7 +84,7 @@ function getQuery(url: string, properties?: Record<string, FunctionConstructor |
|
|||
return query2;
|
||||
}
|
||||
|
||||
const withRouter = (Component: React.ComponentType<any>, { path, properties }: {path?: string, properties?: Record<string, FunctionConstructor | WechatMiniprogram.Component.AllProperty> }) => {
|
||||
const withRouter = (Component: React.ComponentType<any>, { path, properties }: { path?: string, properties?: Record<string, any> }) => {
|
||||
const ComponentWithRouterProp = (props: any) => {
|
||||
const location = useLocation();
|
||||
const routerParams = useParams(); // 取路由 xx/:abbr 通过这个函数取到
|
||||
|
|
|
|||
|
|
@ -283,15 +283,13 @@ export type OakComponentProperties<
|
|||
T extends keyof ED> = Partial<{
|
||||
oakPath: string;
|
||||
oakId: string;
|
||||
oakProjection: ED[T]['Selection']['data'];
|
||||
// oakProjection: ED[T]['Selection']['data'];
|
||||
oakFrom: string;
|
||||
oakParentEntity: string;
|
||||
oakDisablePulldownRefresh: boolean;
|
||||
oakAutoUnmount: boolean;
|
||||
oakActions: ED[T]['Action'][];
|
||||
oakCascadeActions: {
|
||||
[K in keyof ED[T]['Schema']]?: ActionDef<ED, keyof ED>[];
|
||||
};
|
||||
oakActions: string;
|
||||
oakCascadeActions: string;
|
||||
}>;
|
||||
|
||||
export type OakListComponentProperties<
|
||||
|
|
@ -299,8 +297,8 @@ export type OakListComponentProperties<
|
|||
T extends keyof ED> = Partial<{
|
||||
oakFilters: NamedFilterItem<ED, T>[];
|
||||
oakSorters: NamedSorterItem<ED, T>[];
|
||||
oakIsPicker: boolean;
|
||||
oakPagination: Pagination;
|
||||
oakProjection: ED[T]['Selection']['data'];
|
||||
// oakPagination: Pagination;
|
||||
}>;
|
||||
|
||||
export type OakNavigateToParameters<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
|
|
@ -311,7 +309,6 @@ export type OakNavigateToParameters<ED extends EntityDict & BaseEntityDict, T ex
|
|||
oakProjection?: ED[T]['Selection']['data'],
|
||||
oakSorters?: Array<NamedSorterItem<ED, T>>,
|
||||
oakFilters?: Array<NamedFilterItem<ED, T>>;
|
||||
oakIsPicker?: boolean;
|
||||
[k: string]: any;
|
||||
};
|
||||
|
||||
|
|
@ -402,9 +399,10 @@ export type OakListComponentMethods<ED extends EntityDict & BaseEntityDict, T ex
|
|||
getFilters: (path?: string) => ED[T]['Selection']['filter'][] | undefined;
|
||||
getFilterByName: (name: string, path?: string) => ED[T]['Selection']['filter'] | undefined;
|
||||
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
setNamedFilters: (filters: NamedFilterItem<ED, T>[], refresh?: boolean, path?: string) => void;
|
||||
removeNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
removeNamedFilterByName: (name: string, refresh?: boolean, path?: string) => void;
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], path?: string) => void;
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[], refresh?: boolean, path?: string) => void;
|
||||
getSorters: (path?: string) => ED[T]['Selection']['sorter'] | undefined;
|
||||
getSorterByName: (name: string, path?: string) => NonNullable<ED[T]['Selection']['sorter']>[number] | undefined;
|
||||
addNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean, path?: string) => void;
|
||||
|
|
@ -456,8 +454,8 @@ type OakListComoponetData<
|
|||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED
|
||||
> = {
|
||||
oakFilters?: NonNullable<ED[T]['Selection']['filter']>[];
|
||||
oakSorters?: NonNullable<ED[T]['Selection']['sorter']>[];
|
||||
// oakFilters?: NonNullable<ED[T]['Selection']['filter']>[];
|
||||
// oakSorters?: NonNullable<ED[T]['Selection']['sorter']>[];
|
||||
oakPagination?: Pagination;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue