新框架的诸多功能和BUG修正

This commit is contained in:
Xu Chang 2022-10-23 23:14:36 +08:00
parent 1cee0aa53a
commit e21280aa3e
14 changed files with 629 additions and 490 deletions

View File

@ -35,7 +35,7 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends C
operation: ED[keyof ED]['Operation'];
}>): Promise<SelectionResult<ED[T]["Schema"], S["data"]>>;
get<T extends keyof ED, S extends ED[T]['Selection']>(entity: T, selection: S, params?: SelectOption): Promise<import("oak-domain/lib/types").SelectRowShape<ED[T]["Schema"], S["data"]>[]>;
judgeRelation(entity: keyof ED, attr: string): string | 0 | 2 | 1 | string[];
judgeRelation(entity: keyof ED, attr: string): string | 0 | 2 | string[] | 1;
bindOnSync(callback: (opRecords: OpRecord<ED>[]) => Promise<void>): void;
unbindOnSync(callback: (opRecords: OpRecord<ED>[]) => Promise<void>): void;
getCachedData(): { [T in keyof ED]?: ED[T]["OpSchema"][] | undefined; };

View File

@ -144,6 +144,7 @@ var Cache = /** @class */ (function (_super) {
return [4 /*yield*/, this.cacheStore.operate(entity, (0, lodash_1.cloneDeep)(operation), context, {
dontCollect: true,
dontCreateOper: true,
dontCreateModi: true,
})];
case 5:
_b.sent();
@ -241,7 +242,7 @@ var Cache = /** @class */ (function (_super) {
return [4 /*yield*/, this.cacheStore.operate(oper.entity, (0, lodash_1.cloneDeep)(oper.operation), context, {
dontCollect: true,
dontCreateOper: true,
blockTrigger: true,
dontCreateModi: true,
})];
case 4:
_b.sent();

View File

@ -21,7 +21,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict, T extends ke
protected loadingMore: boolean;
protected executing: boolean;
protected operations: Operation<ED, T>[];
protected modiIds: string[];
protected modies: BaseEntityDict['modi']['OpSchema'][];
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: Node<ED, keyof ED, Cxt, AD>);
getEntity(): T;
protected abstract getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string;
@ -30,7 +30,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict, T extends ke
/**
* modi
*/
getModiIds(child: Node<ED, keyof ED, Cxt, AD>): string[];
getModies(child: Node<ED, keyof ED, Cxt, AD>): BaseEntityDict['modi']['OpSchema'][];
setDirty(): void;
isDirty(): boolean;
isLoading(): boolean;
@ -39,7 +39,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict, T extends ke
setExecuting(executing: boolean): void;
getParent(): Node<ED, keyof ED, Cxt, AD> | undefined;
protected getProjection(): Promise<ED[T]["Selection"]["data"]>;
protected judgeRelation(attr: string): string | 0 | 2 | 1 | string[];
protected judgeRelation(attr: string): string | 0 | 2 | string[] | 1;
protected contains(filter: ED[T]['Selection']['filter'], conditionalFilter: ED[T]['Selection']['filter']): boolean;
protected repel(filter1: ED[T]['Selection']['filter'], filter2: ED[T]['Selection']['filter']): boolean;
}
@ -101,7 +101,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
};
addChild(path: string, node: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>): void;
removeChild(path: string): void;
getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>>;
getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']> | undefined>;
doBeforeTrigger(): Promise<void>;
doAfterTrigger(): Promise<void>;
addOperation(oper: Omit<ED[T]['Operation'], 'id'>, beforeExecute?: Operation<ED, T>['beforeExecute'], afterExecute?: Operation<ED, T>['afterExecute']): Promise<void>;
@ -129,10 +129,10 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
private schema;
private root;
constructor(aspectWrapper: AspectWrapper<ED, Cxt, AD>, cache: Cache<ED, Cxt, AD>, schema: StorageSchema<ED>);
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): Promise<ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD>>;
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): Promise<ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD> | undefined>;
private findNode;
destroyNode(path: string): void;
getFreshValue(path: string): Promise<SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]>> | Promise<SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]>[]>;
getFreshValue(path: string): Promise<SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]> | undefined> | Promise<SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]>[]> | undefined;
isDirty(path: string): boolean;
addOperation<T extends keyof ED>(path: string, operation: Omit<ED[T]['Operation'], 'id'>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): Promise<void>;
isLoading(path: string): boolean;
@ -157,7 +157,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
removeNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
removeNamedSorterByName<T extends keyof ED>(path: string, name: string, refresh?: boolean): Promise<void>;
tryExecute(path: string): Promise<boolean>;
execute(path: string): Promise<ED[keyof ED]["Operation"][] | undefined>;
execute(path: string, operation?: ED[keyof ED]['Operation']): Promise<ED[keyof ED]["Operation"][] | undefined>;
clean(path: string): void;
getRoot(): Record<string, SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>>;
}

View File

@ -5,6 +5,7 @@ var tslib_1 = require("tslib");
var assert_1 = require("oak-domain/lib/utils/assert");
var lodash_1 = require("oak-domain/lib/utils/lodash");
var filter_1 = require("oak-domain/lib/store/filter");
var modi_1 = require("oak-domain/lib/store/modi");
var relation_1 = require("oak-domain/lib/store/relation");
var Feature_1 = require("../types/Feature");
var Node = /** @class */ (function () {
@ -19,7 +20,7 @@ var Node = /** @class */ (function () {
this.loadingMore = false;
this.executing = false;
this.operations = [];
this.modiIds = [];
this.modies = [];
}
Node.prototype.getEntity = function () {
return this.entity;
@ -27,12 +28,12 @@ var Node = /** @class */ (function () {
/**
* 这个函数从某个结点向父亲查询看所在路径上是否有需要被应用的modi
*/
Node.prototype.getModiIds = function (child) {
Node.prototype.getModies = function (child) {
var childPath = this.getChildPath(child);
if (childPath.includes(':')) {
var modiIds = this.modiIds;
if (childPath.includes(':next')) {
var modies = this.modies;
// 如果是需要modi的路径在这里应该就可以返回了目前应该不存在modi嵌套modi
return modiIds;
return modies;
}
var toModi = this.schema[this.entity].toModi;
if (toModi) {
@ -40,7 +41,7 @@ var Node = /** @class */ (function () {
return [];
}
if (this.parent) {
return this.parent.getModiIds(this);
return this.parent.getModies(this);
}
return [];
};
@ -108,7 +109,8 @@ var DEFAULT_PAGINATION = {
more: true,
};
function mergeOperationData(entity, schema, from, into) {
for (var attr in from) {
var _loop_1 = function (attr) {
var e_1, _a;
if (!into[attr]) {
into[attr] = from[attr];
}
@ -126,27 +128,65 @@ function mergeOperationData(entity, schema, from, into) {
(0, assert_1.assert)(!result);
}
else if (rel instanceof Array) {
// 这种情况还不是很清楚,感觉不太可能跑的到 by Xc
(0, assert_1.assert)(false);
/* const [entity2] = rel;
const {
index,
eliminated,
} = findOperationToMerge(entity2, schema, from[attr] as any, into[attr] as any);
if (!index) {
(into[attr] as any).push(from[attr]);
/**
* 两个一对多的list要合并直接合并list就可以了前端设计上应该不可能出现两个一对多的list相交的case
* $extraFile$XXX:1 $extraFile$XXX:2
*/
// (into[attr] as unknown as ED[keyof ED]['Operation'][]).push(...(from[attr] as unknown as ED[keyof ED]['Operation'][]));
var _b = tslib_1.__read(rel, 1), entity2_1 = _b[0];
var mergeInner = function (item) {
var e_2, _a;
var _b = findOperationToMerge(entity2_1, schema, item, into[attr]), index = _b.index, eliminated = _b.eliminated;
if (!index) {
into[attr].push(item);
}
else {
var result2 = mergeOperationOper(entity2_1, schema, item, index);
if (result2) {
(0, lodash_1.pull)(into[attr], index);
}
}
try {
for (var eliminated_1 = (e_2 = void 0, tslib_1.__values(eliminated)), eliminated_1_1 = eliminated_1.next(); !eliminated_1_1.done; eliminated_1_1 = eliminated_1.next()) {
var eli = eliminated_1_1.value;
(0, lodash_1.pull)(into[attr], eli);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (eliminated_1_1 && !eliminated_1_1.done && (_a = eliminated_1.return)) _a.call(eliminated_1);
}
finally { if (e_2) throw e_2.error; }
}
};
if (from[attr] instanceof Array) {
try {
for (var _c = (e_1 = void 0, tslib_1.__values(from[attr])), _d = _c.next(); !_d.done; _d = _c.next()) {
var operation = _d.value;
mergeInner(operation);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
}
else {
const result2 = mergeOperationOper(entity2, schema, from[attr] as any, index);
if (result2) {
pull(from[attr] as any, index);
}
} */
(0, assert_1.assert)(false); // 前台感觉是跑不出这个case的
mergeInner(from[attr]);
}
}
else {
into[attr] = from[attr];
}
}
};
for (var attr in from) {
_loop_1(attr);
}
}
/**
@ -157,37 +197,24 @@ function mergeOperationData(entity, schema, from, into) {
* @param into
*/
function mergeOperationOper(entity, schema, from, into) {
var e_1, _a, e_2, _b;
var e_3, _a, e_4, _b;
var action = from.action, data = from.data, filter = from.filter;
var dataTo = into.data;
if (action === into.action) {
switch (action) {
case 'create': {
/**
* 前端的页面设计如果要merge两个create动作要么都是single要么都是array
* 不应该出现array和single并存的case
*/
if (dataTo instanceof Array) {
if (data instanceof Array) {
data.forEach(function (ele) { return (0, assert_1.assert)(ele.id); });
dataTo.push.apply(dataTo, tslib_1.__spreadArray([], tslib_1.__read(data), false));
}
else {
(0, assert_1.assert)(data.id);
dataTo.push(data);
}
}
else if (!(data instanceof Array) && !data.id) {
// 特殊情况其实就是单次create
mergeOperationData(entity, schema, data, dataTo);
(0, assert_1.assert)(data instanceof Array);
data.forEach(function (ele) { return (0, assert_1.assert)(ele.id); });
dataTo.push.apply(dataTo, tslib_1.__spreadArray([], tslib_1.__read(data), false));
}
else {
var data3 = [dataTo];
if (data instanceof Array) {
data3.push.apply(data3, tslib_1.__spreadArray([], tslib_1.__read(data), false));
}
else {
data3.push(data);
}
Object.assign(into, {
data: data3,
});
(0, assert_1.assert)(!(data instanceof Array));
mergeOperationData(entity, schema, data, dataTo);
}
return false;
}
@ -211,12 +238,12 @@ function mergeOperationOper(entity, schema, from, into) {
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (operData_1_1 && !operData_1_1.done && (_a = operData_1.return)) _a.call(operData_1);
}
finally { if (e_1) throw e_1.error; }
finally { if (e_3) throw e_3.error; }
}
}
else {
@ -247,12 +274,12 @@ function mergeOperationOper(entity, schema, from, into) {
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (operData_2_1 && !operData_2_1.done && (_b = operData_2.return)) _b.call(operData_2);
}
finally { if (e_2) throw e_2.error; }
finally { if (e_4) throw e_4.error; }
}
}
else {
@ -276,19 +303,24 @@ function mergeOperationTrigger(from, to) {
}
}
function findOperationToMerge(entity, schema, from, existed) {
var e_3, _a, e_4, _b, e_5, _c;
var e_5, _a, e_6, _b, e_7, _c;
var action = from.action, filter = from.filter;
var eliminated = [];
if (action === 'create') {
// action不可能和当前已经的某个动作发生merge
return {
index: undefined,
eliminated: eliminated,
};
}
try {
for (var existed_1 = tslib_1.__values(existed), existed_1_1 = existed_1.next(); !existed_1_1.done; existed_1_1 = existed_1.next()) {
var toOperation = existed_1_1.value;
if (action === toOperation.action) {
switch (action) {
case 'create': {
return {
index: toOperation,
eliminated: eliminated,
};
// 两个create不可能merge如果是many to one则不用走到这里判断
break;
}
default: {
// update/remove只合并filter完全相同的项
@ -309,7 +341,7 @@ function findOperationToMerge(entity, schema, from, existed) {
var operData = toOperation.data;
if (operData instanceof Array) {
try {
for (var operData_3 = (e_4 = void 0, tslib_1.__values(operData)), operData_3_1 = operData_3.next(); !operData_3_1.done; operData_3_1 = operData_3.next()) {
for (var operData_3 = (e_6 = void 0, tslib_1.__values(operData)), operData_3_1 = operData_3.next(); !operData_3_1.done; operData_3_1 = operData_3.next()) {
var operData2 = operData_3_1.value;
if (operData2.id === filter.id) {
return {
@ -319,12 +351,12 @@ function findOperationToMerge(entity, schema, from, existed) {
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (operData_3_1 && !operData_3_1.done && (_b = operData_3.return)) _b.call(operData_3);
}
finally { if (e_4) throw e_4.error; }
finally { if (e_6) throw e_6.error; }
}
}
else {
@ -342,7 +374,7 @@ function findOperationToMerge(entity, schema, from, existed) {
var operData = toOperation.data;
if (operData instanceof Array) {
try {
for (var operData_4 = (e_5 = void 0, tslib_1.__values(operData)), operData_4_1 = operData_4.next(); !operData_4_1.done; operData_4_1 = operData_4.next()) {
for (var operData_4 = (e_7 = void 0, tslib_1.__values(operData)), operData_4_1 = operData_4.next(); !operData_4_1.done; operData_4_1 = operData_4.next()) {
var operData2 = operData_4_1.value;
if (operData2.id === filter.id) {
return {
@ -352,12 +384,12 @@ function findOperationToMerge(entity, schema, from, existed) {
}
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (operData_4_1 && !operData_4_1.done && (_c = operData_4.return)) _c.call(operData_4);
}
finally { if (e_5) throw e_5.error; }
finally { if (e_7) throw e_7.error; }
}
}
else {
@ -380,12 +412,12 @@ function findOperationToMerge(entity, schema, from, existed) {
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (existed_1_1 && !existed_1_1.done && (_a = existed_1.return)) _a.call(existed_1);
}
finally { if (e_3) throw e_3.error; }
finally { if (e_5) throw e_5.error; }
}
// 到这儿说明merge不了
return {
@ -400,7 +432,7 @@ function findOperationToMerge(entity, schema, from, existed) {
* @return 是否merge成功
*/
function tryMergeOperationToExisted(entity, schema, operation, existed) {
var e_6, _a;
var e_8, _a;
var oper = operation.oper;
// 有动作的operation是不能合并的
var existedOperations = existed.filter(function (ele) { return !ele.afterExecute && !ele.beforeExecute; }).map(function (ele) { return ele.oper; });
@ -418,22 +450,22 @@ function tryMergeOperationToExisted(entity, schema, operation, existed) {
mergeOperationTrigger(operation, origin_1);
}
}
var _loop_1 = function (eli) {
var _loop_2 = function (eli) {
var origin_2 = existed.find(function (ele) { return ele.oper === eli; });
(0, lodash_1.pull)(existed, origin_2);
};
try {
for (var eliminated_1 = tslib_1.__values(eliminated), eliminated_1_1 = eliminated_1.next(); !eliminated_1_1.done; eliminated_1_1 = eliminated_1.next()) {
var eli = eliminated_1_1.value;
_loop_1(eli);
for (var eliminated_2 = tslib_1.__values(eliminated), eliminated_2_1 = eliminated_2.next(); !eliminated_2_1.done; eliminated_2_1 = eliminated_2.next()) {
var eli = eliminated_2_1.value;
_loop_2(eli);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
catch (e_8_1) { e_8 = { error: e_8_1 }; }
finally {
try {
if (eliminated_1_1 && !eliminated_1_1.done && (_a = eliminated_1.return)) _a.call(eliminated_1);
if (eliminated_2_1 && !eliminated_2_1.done && (_a = eliminated_2.return)) _a.call(eliminated_2);
}
finally { if (e_6) throw e_6.error; }
finally { if (e_8) throw e_8.error; }
}
return !!index;
}
@ -451,7 +483,7 @@ var ListNode = /** @class */ (function (_super) {
return _this;
}
ListNode.prototype.getChildPath = function (child) {
var e_7, _a;
var e_9, _a;
var idx = 0;
try {
for (var _b = tslib_1.__values(this.children), _c = _b.next(); !_c.done; _c = _b.next()) {
@ -462,19 +494,19 @@ var ListNode = /** @class */ (function (_super) {
idx++;
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
catch (e_9_1) { e_9 = { error: e_9_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_7) throw e_7.error; }
finally { if (e_9) throw e_9.error; }
}
(0, assert_1.assert)(false);
};
ListNode.prototype.onCacheSync = function (records) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var createdIds, records_1, records_1_1, record, a, _a, e, d, id, currentIds, _b, sorter, filters, filter, value;
var e_8, _c;
var e_10, _c;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
@ -510,12 +542,12 @@ var ListNode = /** @class */ (function (_super) {
}
}
}
catch (e_8_1) { e_8 = { error: e_8_1 }; }
catch (e_10_1) { e_10 = { error: e_10_1 }; }
finally {
try {
if (records_1_1 && !records_1_1.done && (_c = records_1.return)) _c.call(records_1);
}
finally { if (e_8) throw e_8.error; }
finally { if (e_10) throw e_10.error; }
}
if (!(createdIds.length > 0)) return [3 /*break*/, 3];
currentIds = this.ids;
@ -545,7 +577,7 @@ var ListNode = /** @class */ (function (_super) {
});
};
ListNode.prototype.destroy = function () {
var e_9, _a;
var e_11, _a;
this.cache.unbindOnSync(this.syncHandler);
try {
for (var _b = tslib_1.__values(this.children), _c = _b.next(); !_c.done; _c = _b.next()) {
@ -553,12 +585,12 @@ var ListNode = /** @class */ (function (_super) {
child.destroy();
}
}
catch (e_9_1) { e_9 = { error: e_9_1 }; }
catch (e_11_1) { e_11 = { error: e_11_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_9) throw e_9.error; }
finally { if (e_11) throw e_11.error; }
}
};
ListNode.prototype.getPagination = function () {
@ -773,8 +805,8 @@ var ListNode = /** @class */ (function (_super) {
};
ListNode.prototype.getFreshValue = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var projection, _a, ids, _b, _c, operation, oper, data, modiIds, operations, result;
var e_10, _d;
var projection, _a, ids, _b, _c, operation, oper, data, modies, operations, result;
var e_12, _d;
var _this = this;
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
@ -805,24 +837,15 @@ var ListNode = /** @class */ (function (_super) {
}
}
}
catch (e_10_1) { e_10 = { error: e_10_1 }; }
catch (e_12_1) { e_12 = { error: e_12_1 }; }
finally {
try {
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
}
finally { if (e_10) throw e_10.error; }
finally { if (e_12) throw e_12.error; }
}
modiIds = this.parent ? this.parent.getModiIds(this) : [];
operations = modiIds.map(function (ele) { return ({
entity: 'modi',
operation: {
action: 'apply',
data: {},
filter: {
id: ele,
},
}
}); });
modies = this.parent ? this.parent.getModies(this) : [];
operations = (0, modi_1.createOperationsFromModies)(modies);
operations.push.apply(operations, tslib_1.__spreadArray([], tslib_1.__read(this.operations.map(function (ele) { return ({
entity: _this.entity,
operation: ele.oper,
@ -872,68 +895,6 @@ var ListNode = /** @class */ (function (_super) {
});
};
ListNode.prototype.doBeforeTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, _b, operation, e_11_1, _c, _d, child, e_12_1;
var e_11, _e, e_12, _f;
return tslib_1.__generator(this, function (_g) {
switch (_g.label) {
case 0:
_g.trys.push([0, 5, 6, 7]);
_a = tslib_1.__values(this.operations), _b = _a.next();
_g.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 4];
operation = _b.value;
if (!operation.beforeExecute) return [3 /*break*/, 3];
return [4 /*yield*/, operation.beforeExecute()];
case 2:
_g.sent();
_g.label = 3;
case 3:
_b = _a.next();
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_11_1 = _g.sent();
e_11 = { error: e_11_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
}
finally { if (e_11) throw e_11.error; }
return [7 /*endfinally*/];
case 7:
_g.trys.push([7, 12, 13, 14]);
_c = tslib_1.__values(this.children), _d = _c.next();
_g.label = 8;
case 8:
if (!!_d.done) return [3 /*break*/, 11];
child = _d.value;
return [4 /*yield*/, child.doBeforeTrigger()];
case 9:
_g.sent();
_g.label = 10;
case 10:
_d = _c.next();
return [3 /*break*/, 8];
case 11: return [3 /*break*/, 14];
case 12:
e_12_1 = _g.sent();
e_12 = { error: e_12_1 };
return [3 /*break*/, 14];
case 13:
try {
if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
}
finally { if (e_12) throw e_12.error; }
return [7 /*endfinally*/];
case 14: return [2 /*return*/];
}
});
});
};
ListNode.prototype.doAfterTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, _b, operation, e_13_1, _c, _d, child, e_14_1;
var e_13, _e, e_14, _f;
@ -946,8 +907,8 @@ var ListNode = /** @class */ (function (_super) {
case 1:
if (!!_b.done) return [3 /*break*/, 4];
operation = _b.value;
if (!operation.afterExecute) return [3 /*break*/, 3];
return [4 /*yield*/, operation.afterExecute()];
if (!operation.beforeExecute) return [3 /*break*/, 3];
return [4 /*yield*/, operation.beforeExecute()];
case 2:
_g.sent();
_g.label = 3;
@ -972,7 +933,7 @@ var ListNode = /** @class */ (function (_super) {
case 8:
if (!!_d.done) return [3 /*break*/, 11];
child = _d.value;
return [4 /*yield*/, child.doAfterTrigger()];
return [4 /*yield*/, child.doBeforeTrigger()];
case 9:
_g.sent();
_g.label = 10;
@ -995,10 +956,72 @@ var ListNode = /** @class */ (function (_super) {
});
});
};
ListNode.prototype.doAfterTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, _b, operation, e_15_1, _c, _d, child, e_16_1;
var e_15, _e, e_16, _f;
return tslib_1.__generator(this, function (_g) {
switch (_g.label) {
case 0:
_g.trys.push([0, 5, 6, 7]);
_a = tslib_1.__values(this.operations), _b = _a.next();
_g.label = 1;
case 1:
if (!!_b.done) return [3 /*break*/, 4];
operation = _b.value;
if (!operation.afterExecute) return [3 /*break*/, 3];
return [4 /*yield*/, operation.afterExecute()];
case 2:
_g.sent();
_g.label = 3;
case 3:
_b = _a.next();
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_15_1 = _g.sent();
e_15 = { error: e_15_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
}
finally { if (e_15) throw e_15.error; }
return [7 /*endfinally*/];
case 7:
_g.trys.push([7, 12, 13, 14]);
_c = tslib_1.__values(this.children), _d = _c.next();
_g.label = 8;
case 8:
if (!!_d.done) return [3 /*break*/, 11];
child = _d.value;
return [4 /*yield*/, child.doAfterTrigger()];
case 9:
_g.sent();
_g.label = 10;
case 10:
_d = _c.next();
return [3 /*break*/, 8];
case 11: return [3 /*break*/, 14];
case 12:
e_16_1 = _g.sent();
e_16 = { error: e_16_1 };
return [3 /*break*/, 14];
case 13:
try {
if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
}
finally { if (e_16) throw e_16.error; }
return [7 /*endfinally*/];
case 14: return [2 /*return*/];
}
});
});
};
ListNode.prototype.composeOperations = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var childOperations, operations, childOperations_1, childOperations_1_1, oper, _a, index, eliminated, result, eliminated_2, eliminated_2_1, eli;
var e_15, _b, e_16, _c;
var childOperations, operations, childOperations_1, childOperations_1_1, oper, _a, index, eliminated, result, eliminated_3, eliminated_3_1, eli;
var e_17, _b, e_18, _c;
var _this = this;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
@ -1041,29 +1064,29 @@ var ListNode = /** @class */ (function (_super) {
operations.push(oper);
}
try {
for (eliminated_2 = (e_16 = void 0, tslib_1.__values(eliminated)), eliminated_2_1 = eliminated_2.next(); !eliminated_2_1.done; eliminated_2_1 = eliminated_2.next()) {
eli = eliminated_2_1.value;
for (eliminated_3 = (e_18 = void 0, tslib_1.__values(eliminated)), eliminated_3_1 = eliminated_3.next(); !eliminated_3_1.done; eliminated_3_1 = eliminated_3.next()) {
eli = eliminated_3_1.value;
if (eli) {
(0, lodash_1.pull)(operations, eli);
}
}
}
catch (e_16_1) { e_16 = { error: e_16_1 }; }
catch (e_18_1) { e_18 = { error: e_18_1 }; }
finally {
try {
if (eliminated_2_1 && !eliminated_2_1.done && (_c = eliminated_2.return)) _c.call(eliminated_2);
if (eliminated_3_1 && !eliminated_3_1.done && (_c = eliminated_3.return)) _c.call(eliminated_3);
}
finally { if (e_16) throw e_16.error; }
finally { if (e_18) throw e_18.error; }
}
}
}
}
catch (e_15_1) { e_15 = { error: e_15_1 }; }
catch (e_17_1) { e_17 = { error: e_17_1 }; }
finally {
try {
if (childOperations_1_1 && !childOperations_1_1.done && (_b = childOperations_1.return)) _b.call(childOperations_1);
}
finally { if (e_15) throw e_15.error; }
finally { if (e_17) throw e_17.error; }
}
return [4 /*yield*/, repairOperations(this.entity, this.schema, operations)];
case 2:
@ -1247,7 +1270,7 @@ var ListNode = /** @class */ (function (_super) {
});
};
ListNode.prototype.clean = function () {
var e_17, _a;
var e_19, _a;
this.dirty = undefined;
this.operations = [];
try {
@ -1256,12 +1279,12 @@ var ListNode = /** @class */ (function (_super) {
child.clean();
}
}
catch (e_17_1) { e_17 = { error: e_17_1 }; }
catch (e_19_1) { e_19 = { error: e_19_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_17) throw e_17.error; }
finally { if (e_19) throw e_19.error; }
}
};
return ListNode;
@ -1373,7 +1396,7 @@ var SingleNode = /** @class */ (function (_super) {
} */
SingleNode.prototype.getFreshValue = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var projection, _a, modiIds, operations, _b, operation, id, result;
var projection, _a, modies, operations, _b, operation, id, result;
var _this = this;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
@ -1388,22 +1411,14 @@ var SingleNode = /** @class */ (function (_super) {
_c.label = 3;
case 3:
projection = _a;
modiIds = this.parent ? this.parent.getModiIds(this) : [];
operations = modiIds.map(function (ele) { return ({
entity: 'modi',
operation: {
action: 'apply',
data: {},
filter: {
id: ele,
},
}
}); });
modies = this.parent ? this.parent.getModies(this) : [];
operations = (0, modi_1.createOperationsFromModies)(modies);
_b = tslib_1.__read(this.operations, 1), operation = _b[0];
id = this.id;
if ((operation === null || operation === void 0 ? void 0 : operation.oper.action) === 'create') {
id = operation.oper.data.id;
}
if (!id) return [3 /*break*/, 5];
operations.push.apply(operations, tslib_1.__spreadArray([], tslib_1.__read(this.operations.map(function (ele) { return ({
entity: _this.entity,
operation: ele.oper,
@ -1417,14 +1432,15 @@ var SingleNode = /** @class */ (function (_super) {
case 4:
result = (_c.sent()).result;
return [2 /*return*/, result[0]];
case 5: return [2 /*return*/];
}
});
});
};
SingleNode.prototype.doBeforeTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, _b, operation, e_18_1, _c, _d, _i, k, child;
var e_18, _e;
var _a, _b, operation, e_20_1, _c, _d, _i, k, child;
var e_20, _e;
return tslib_1.__generator(this, function (_f) {
switch (_f.label) {
case 0:
@ -1444,14 +1460,14 @@ var SingleNode = /** @class */ (function (_super) {
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_18_1 = _f.sent();
e_18 = { error: e_18_1 };
e_20_1 = _f.sent();
e_20 = { error: e_20_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
}
finally { if (e_18) throw e_18.error; }
finally { if (e_20) throw e_20.error; }
return [7 /*endfinally*/];
case 7:
_c = [];
@ -1477,8 +1493,8 @@ var SingleNode = /** @class */ (function (_super) {
};
SingleNode.prototype.doAfterTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, _b, operation, e_19_1, _c, _d, _i, k, child;
var e_19, _e;
var _a, _b, operation, e_21_1, _c, _d, _i, k, child;
var e_21, _e;
return tslib_1.__generator(this, function (_f) {
switch (_f.label) {
case 0:
@ -1498,14 +1514,14 @@ var SingleNode = /** @class */ (function (_super) {
return [3 /*break*/, 1];
case 4: return [3 /*break*/, 7];
case 5:
e_19_1 = _f.sent();
e_19 = { error: e_19_1 };
e_21_1 = _f.sent();
e_21 = { error: e_21_1 };
return [3 /*break*/, 7];
case 6:
try {
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
}
finally { if (e_19) throw e_19.error; }
finally { if (e_21) throw e_21.error; }
return [7 /*endfinally*/];
case 7:
_c = [];
@ -1531,10 +1547,10 @@ var SingleNode = /** @class */ (function (_super) {
};
SingleNode.prototype.addOperation = function (oper, beforeExecute, afterExecute) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var operation, _a, _b, _c, _d, _e, _f, _g, current;
var _h, _j;
return tslib_1.__generator(this, function (_k) {
switch (_k.label) {
var operation, _a, _b, _c, _d, _e, _f, result;
var _g, _h;
return tslib_1.__generator(this, function (_j) {
switch (_j.label) {
case 0:
if (oper.action !== 'create') {
(0, assert_1.assert)(this.id);
@ -1558,26 +1574,25 @@ var SingleNode = /** @class */ (function (_super) {
if (!(oper.action === 'create')) return [3 /*break*/, 2];
_b = (_a = Object).assign;
_c = [oper.data];
_h = {};
_g = {};
return [4 /*yield*/, generateNewId()];
case 1:
_b.apply(_a, _c.concat([(_h.id = _k.sent(),
_h)]));
_k.label = 2;
_b.apply(_a, _c.concat([(_g.id = _j.sent(),
_g)]));
_j.label = 2;
case 2:
_e = (_d = Object).assign;
_f = [oper];
_j = {};
_h = {};
return [4 /*yield*/, generateNewId()];
case 3:
_e.apply(_d, _f.concat([(_j.id = _k.sent(), _j)]));
_e.apply(_d, _f.concat([(_h.id = _j.sent(), _h)]));
this.operations.push(operation);
return [3 /*break*/, 5];
case 4:
_g = tslib_1.__read(this.operations, 1), current = _g[0];
Object.assign(current.oper.data, oper.data);
mergeOperationTrigger(operation, current);
_k.label = 5;
result = mergeOperationOper(this.entity, this.schema, oper, this.operations[0].oper);
(0, assert_1.assert)(!result);
_j.label = 5;
case 5:
this.setDirty();
return [2 /*return*/];
@ -1588,7 +1603,7 @@ var SingleNode = /** @class */ (function (_super) {
SingleNode.prototype.composeOperations = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var childOperations, operations, _a, _b, _c, _d, childOperations_2, childOperations_2_1, oper;
var _e, _f, e_20, _g;
var _e, _f, e_22, _g;
var _this = this;
return tslib_1.__generator(this, function (_h) {
switch (_h.label) {
@ -1620,16 +1635,14 @@ var SingleNode = /** @class */ (function (_super) {
ele2 = sliceIdx > 0 ? ele.slice(0, sliceIdx) : ele;
if (this.id) {
return [2 /*return*/, {
oper: {
id: 'dummy',
action: 'update',
data: (_a = {},
_a[ele2] = subOper,
_a),
filter: {
id: this.id,
}
},
id: 'dummy',
action: 'update',
data: (_a = {},
_a[ele2] = subOper,
_a),
filter: {
id: this.id,
}
}];
}
else {
@ -1687,12 +1700,12 @@ var SingleNode = /** @class */ (function (_super) {
}
}
}
catch (e_20_1) { e_20 = { error: e_20_1 }; }
catch (e_22_1) { e_22 = { error: e_22_1 }; }
finally {
try {
if (childOperations_2_1 && !childOperations_2_1.done && (_g = childOperations_2.return)) _g.call(childOperations_2);
}
finally { if (e_20) throw e_20.error; }
finally { if (e_22) throw e_22.error; }
}
return [4 /*yield*/, repairOperations(this.entity, this.schema, operations)];
case 7:
@ -1774,7 +1787,7 @@ var SingleNode = /** @class */ (function (_super) {
// 对于modi对象在此缓存
if (this.schema[this.entity].toModi) {
modi$entity = value.modi$entity;
this.modiIds = modi$entity.map(function (ele) { return ele.id; });
this.modies = modi$entity;
}
this.loading = false;
return [3 /*break*/, 5];
@ -1875,8 +1888,8 @@ function repairOperations(entity, schema, operations) {
});
});
}
var operations_1, operations_1_1, operation, _a, data, data_1, data_1_1, d, e_21_1, e_22_1;
var e_22, _b, e_21, _c;
var operations_1, operations_1_1, operation, _a, data, data_1, data_1_1, d, e_23_1, e_24_1;
var e_24, _b, e_23, _c;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
@ -1898,7 +1911,7 @@ function repairOperations(entity, schema, operations) {
_d.label = 4;
case 4:
_d.trys.push([4, 9, 10, 11]);
data_1 = (e_21 = void 0, tslib_1.__values(data)), data_1_1 = data_1.next();
data_1 = (e_23 = void 0, tslib_1.__values(data)), data_1_1 = data_1.next();
_d.label = 5;
case 5:
if (!!data_1_1.done) return [3 /*break*/, 8];
@ -1912,14 +1925,14 @@ function repairOperations(entity, schema, operations) {
return [3 /*break*/, 5];
case 8: return [3 /*break*/, 11];
case 9:
e_21_1 = _d.sent();
e_21 = { error: e_21_1 };
e_23_1 = _d.sent();
e_23 = { error: e_23_1 };
return [3 /*break*/, 11];
case 10:
try {
if (data_1_1 && !data_1_1.done && (_c = data_1.return)) _c.call(data_1);
}
finally { if (e_21) throw e_21.error; }
finally { if (e_23) throw e_23.error; }
return [7 /*endfinally*/];
case 11: return [3 /*break*/, 14];
case 12: return [4 /*yield*/, repairData(entity, data)];
@ -1931,14 +1944,14 @@ function repairOperations(entity, schema, operations) {
return [3 /*break*/, 1];
case 15: return [3 /*break*/, 18];
case 16:
e_22_1 = _d.sent();
e_22 = { error: e_22_1 };
e_24_1 = _d.sent();
e_24 = { error: e_24_1 };
return [3 /*break*/, 18];
case 17:
try {
if (operations_1_1 && !operations_1_1.done && (_b = operations_1.return)) _b.call(operations_1);
}
finally { if (e_22) throw e_22.error; }
finally { if (e_24) throw e_24.error; }
return [7 /*endfinally*/];
case 18: return [2 /*return*/];
}
@ -1962,6 +1975,9 @@ var RunningTree = /** @class */ (function (_super) {
case 0:
entity = options.entity, pagination = options.pagination, fullPath = options.path, filters = options.filters, sorters = options.sorters, projection = options.projection, isList = options.isList, isPicker = options.isPicker, id = options.id;
_a = analyzePath(fullPath), parent = _a.parent, path = _a.path;
if (this.findNode(fullPath)) {
return [2 /*return*/];
}
parentNode = parent ? this.findNode(parent) : undefined;
if (!(typeof projection === 'function')) return [3 /*break*/, 2];
return [4 /*yield*/, projection()];
@ -1999,6 +2015,9 @@ var RunningTree = /** @class */ (function (_super) {
var node = this.root[paths[0]];
var iter = 1;
while (iter < paths.length && node) {
if (!node) {
return;
}
var childPath = paths[iter];
iter++;
node = node.getChild(childPath);
@ -2248,7 +2267,7 @@ var RunningTree = /** @class */ (function (_super) {
return [4 /*yield*/, node.composeOperations()];
case 1:
operations = _a.sent();
if (!operations) return [3 /*break*/, 3];
if (!(operations && operations.length > 0)) return [3 /*break*/, 3];
return [4 /*yield*/, this.cache.tryRedoOperations(node.getEntity(), operations)];
case 2: return [2 /*return*/, _a.sent()];
case 3: return [2 /*return*/, false];
@ -2256,42 +2275,48 @@ var RunningTree = /** @class */ (function (_super) {
});
});
};
RunningTree.prototype.execute = function (path) {
RunningTree.prototype.execute = function (path, operation) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var node, operations, err_3;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
node = this.findNode(path);
if (!operation) return [3 /*break*/, 2];
return [4 /*yield*/, node.addOperation(operation)];
case 1:
_a.sent();
_a.label = 2;
case 2:
(0, assert_1.assert)(node.isDirty());
node.setExecuting(true);
_a.label = 1;
case 1:
_a.trys.push([1, 6, , 7]);
_a.label = 3;
case 3:
_a.trys.push([3, 8, , 9]);
return [4 /*yield*/, node.doBeforeTrigger()];
case 2:
case 4:
_a.sent();
return [4 /*yield*/, node.composeOperations()];
case 3:
case 5:
operations = _a.sent();
return [4 /*yield*/, this.getAspectWrapper().exec('operate', {
entity: node.getEntity(),
operation: operations.filter(function (ele) { return !!ele; }),
})];
case 4:
case 6:
_a.sent();
return [4 /*yield*/, node.doAfterTrigger()];
case 5:
case 7:
_a.sent();
// 清空缓存
node.clean();
node.setExecuting(false);
return [2 /*return*/, operations];
case 6:
case 8:
err_3 = _a.sent();
node.setExecuting(false);
throw err_3;
case 7: return [2 /*return*/];
case 9: return [2 /*return*/];
}
});
});

View File

@ -7,7 +7,7 @@ export declare function onPathSet<ED extends EntityDict & BaseEntityDict, T exte
export declare function reRender<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, option: OakComponentOption<ED, T, Cxt, any, any, any, any, any, {}, {}, {}>, extra?: Record<string, any>): Promise<void>;
export declare function refresh<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>): Promise<void>;
export declare function loadMore<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>): Promise<void>;
export declare function execute<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, path?: string): Promise<ED[keyof ED]["Operation"][] | undefined>;
export declare function execute<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, operation?: ED[T]['Operation']): Promise<ED[keyof ED]["Operation"][] | undefined>;
export declare function callPicker<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, attr: string, params?: Record<string, any>): void;
export declare function setUpdateData<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, attr: string, data: any): Promise<void>;
export declare function setMultiAttrUpdateData<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>, data: Record<string, any>): Promise<void>;

View File

@ -88,7 +88,7 @@ function onPathSet(option) {
_loop_2 = function (ele) {
var _f;
var sorter = ele.sorter, name_2 = ele["#name"];
sorters.push((_f = {
sorters2.push((_f = {
sorter: typeof sorter === 'function'
? function () {
return sorter({
@ -118,33 +118,46 @@ function onPathSet(option) {
}
oakPath2 = oakPath || path;
(0, assert_1.assert)(oakPath2, '没有正确的path信息请检查是否配置正确');
features.runningTree.createNode({
path: oakPath2,
entity: (oakEntity || entity),
isList: isList,
isPicker: oakIsPicker,
projection: proj,
pagination: pagination,
filters: filters2,
sorters: sorters2,
});
return [4 /*yield*/, features.runningTree.createNode({
path: oakPath2,
entity: (oakEntity || entity),
isList: isList,
isPicker: oakIsPicker,
projection: proj,
pagination: pagination,
filters: filters2,
sorters: sorters2,
})];
case 1:
_d.sent();
Object.assign(this.state, {
oakEntity: (oakEntity || entity),
oakFullpath: oakPath2,
oakIsReady: true,
});
if (!isList) return [3 /*break*/, 2];
if (!isList) return [3 /*break*/, 3];
return [4 /*yield*/, features.runningTree.refresh(oakPath2)];
case 1:
_d.sent();
return [3 /*break*/, 4];
case 2:
if (!oakId) return [3 /*break*/, 4];
return [4 /*yield*/, features.runningTree.setId(oakPath2, oakId)];
case 3:
_d.sent();
_d.label = 4;
case 4: return [2 /*return*/];
return [3 /*break*/, 6];
case 3:
if (!oakId) return [3 /*break*/, 5];
return [4 /*yield*/, features.runningTree.setId(oakPath2, oakId)];
case 4:
_d.sent();
return [3 /*break*/, 6];
case 5:
if (oakEntity || entity) {
this.reRender();
}
else {
// 啥都没有也要为了oakFullpath刷新一次
this.setState({
oakFullpath: oakPath2,
});
}
_d.label = 6;
case 6: return [2 /*return*/];
}
});
});
@ -152,14 +165,15 @@ function onPathSet(option) {
exports.onPathSet = onPathSet;
function reRender(option, extra) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var features, formData, rows, oakDirty, oakLoading, oakPullDownRefreshLoading, oakLoadingMore, oakExecuting, data, _a, k, oakAllowExecuting, err_1, data, _b;
var features, formData, rows, oakDirty, oakLoading, oakPullDownRefreshLoading, oakLoadingMore, oakExecuting, data, _a, k, oakAllowExecuting, err_1, actions, testResult, oakLegalActions, data, _b;
var _c;
var _this = this;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
features = this.features;
formData = option.formData;
if (!(this.state.oakEntity && this.state.oakFullpath)) return [3 /*break*/, 9];
if (!(this.state.oakEntity && this.state.oakFullpath)) return [3 /*break*/, 11];
return [4 /*yield*/, this.features.runningTree.getFreshValue(this.state.oakFullpath)];
case 1:
rows = _d.sent();
@ -221,28 +235,53 @@ function reRender(option, extra) {
Object.assign(data, {
oakAllowExecuting: oakAllowExecuting,
});
this.setState(data);
return [3 /*break*/, 13];
actions = this.props.oakActions || option.actions;
if (!(actions && actions.length > 0)) return [3 /*break*/, 10];
(0, assert_1.assert)(this.props.oakId); // actions必须配合id来使用
return [4 /*yield*/, Promise.all(actions.map(function (ele) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = {
action: ele
};
return [4 /*yield*/, this.checkOperation(this.state.oakEntity, ele, { id: this.props.oakId }, ['user', 'row'])];
case 1: return [2 /*return*/, (_a.result = _b.sent(),
_a)];
}
});
}); }))];
case 9:
if (!formData) return [3 /*break*/, 11];
testResult = _d.sent();
oakLegalActions = testResult.filter(function (ele) { return ele.result; }).map(function (ele) { return ele.action; });
Object.assign(data, {
oakLegalActions: oakLegalActions,
});
_d.label = 10;
case 10:
this.setState(data);
return [3 /*break*/, 15];
case 11:
if (!formData) return [3 /*break*/, 13];
return [4 /*yield*/, formData.call(this, {
features: features,
props: this.props,
})];
case 10:
_b = _d.sent();
return [3 /*break*/, 12];
case 11:
_b = {};
_d.label = 12;
case 12:
_b = _d.sent();
return [3 /*break*/, 14];
case 13:
_b = {};
_d.label = 14;
case 14:
data = _b;
if (extra) {
Object.assign(data, extra);
}
this.setState(data);
_d.label = 13;
case 13: return [2 /*return*/];
_d.label = 15;
case 15: return [2 /*return*/];
}
});
});
@ -302,9 +341,10 @@ function loadMore() {
});
}
exports.loadMore = loadMore;
function execute(path) {
function execute(operation) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var fullpath, result, err_4, attrs, message;
var result, err_4, attrs, entity_1, message, attrNames;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -318,10 +358,7 @@ function execute(path) {
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
fullpath = path
? "".concat(this.state.oakFullpath, ".").concat(path)
: this.state.oakFullpath;
return [4 /*yield*/, this.features.runningTree.execute(fullpath)];
return [4 /*yield*/, this.features.runningTree.execute(this.state.oakFullpath, operation)];
case 2:
result = _a.sent();
this.setState({
@ -337,13 +374,12 @@ function execute(path) {
if (err_4 instanceof types_1.OakUserException) {
if (err_4 instanceof types_1.OakInputIllegalException) {
attrs = err_4.getAttributes();
entity_1 = err_4.getEntity();
message = err_4.message;
this.setState({
oakFocused: {
attr: attrs[0],
message: message,
},
oakExecuting: false,
attrNames = attrs.map(function (attr) { return _this.t("".concat(entity_1, ":attr.").concat(attr)); }).filter(function (ele) { return !!ele; });
this.setMessage({
type: 'error',
content: attrNames.length > 0 ? "\u300C".concat(attrNames.join(','), "\u300D").concat(message) : message,
});
throw err_4;
}

View File

@ -21,7 +21,7 @@ var OakComponentBase = /** @class */ (function (_super) {
page_common_1.unsubscribe.call(this);
};
OakComponentBase.prototype.onPathSet = function () {
page_common_1.onPathSet.call(this, this.option);
return page_common_1.onPathSet.call(this, this.option);
};
OakComponentBase.prototype.triggerEvent = function (name, detail, options) {
};
@ -200,14 +200,19 @@ var OakComponentBase = /** @class */ (function (_super) {
if (params === void 0) { params = {}; }
return page_common_1.callPicker.call(this, attr, params);
};
OakComponentBase.prototype.execute = function () {
return page_common_1.execute.call(this);
OakComponentBase.prototype.execute = function (operation) {
return page_common_1.execute.call(this, operation);
};
OakComponentBase.prototype.getFreshValue = function (path) {
var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) : this.state.oakFullpath;
return this.features.runningTree.getFreshValue(path2);
};
OakComponentBase.prototype.checkOperation = function (entity, action, filter, checkerTypes) {
return this.features.cache.checkOperation(entity, action, filter, checkerTypes);
};
OakComponentBase.prototype.tryExecute = function () {
return this.features.runningTree.tryExecute(this.state.oakFullpath);
OakComponentBase.prototype.tryExecute = function (path) {
var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) : this.state.oakFullpath;
return this.features.runningTree.tryExecute(path2);
};
OakComponentBase.prototype.refresh = function () {
return page_common_1.refresh.call(this);
@ -523,34 +528,60 @@ function createComponent(option, features, exceptionRouterDict) {
this.isReachBottom = isCurrentReachBottom;
};
OakComponentWrapper.prototype.componentDidMount = function () {
this.registerPageScroll();
this.subscribe();
var oakPath = this.props.oakPath;
if (oakPath || this.iAmThePage() && path) {
this.onPathSet();
}
else {
this.reRender();
}
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.attached) && lifetimes.attached.call(this);
(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);
return tslib_1.__awaiter(this, void 0, void 0, function () {
var oakPath;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.registerPageScroll();
this.subscribe();
oakPath = this.props.oakPath;
if (!(oakPath || this.iAmThePage() && path)) return [3 /*break*/, 2];
return [4 /*yield*/, this.onPathSet()];
case 1:
_a.sent();
return [3 /*break*/, 3];
case 2:
this.reRender();
_a.label = 3;
case 3:
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.attached) && lifetimes.attached.call(this);
(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);
return [2 /*return*/];
}
});
});
};
OakComponentWrapper.prototype.componentWillUnmount = function () {
this.state.oakFullpath && this.features.runningTree.destroyNode(this.state.oakFullpath);
this.state.oakFullpath && (this.iAmThePage() || this.props.oakAutoUnmount) && this.features.runningTree.destroyNode(this.state.oakFullpath);
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.detached) && lifetimes.detached.call(this);
this.unsubscribe();
this.unregisterPageScroll();
};
OakComponentWrapper.prototype.componentDidUpdate = function (prevProps, prevState) {
if (!prevProps.oakPath && this.props.oakPath) {
this.onPathSet();
}
if (this.props.oakId !== prevProps.oakId) {
this.setId(this.props.oakId);
}
// todo 这里似乎还可能对oakProjection这些东西加以更新等遇到再添加 by Xc
fn && fn.call(this, prevProps, prevState);
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(!prevProps.oakPath && this.props.oakPath)) return [3 /*break*/, 2];
return [4 /*yield*/, this.onPathSet()];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!(this.props.oakId !== prevProps.oakId)) return [3 /*break*/, 4];
return [4 /*yield*/, this.setId(this.props.oakId)];
case 3:
_a.sent();
_a.label = 4;
case 4:
// todo 这里似乎还可能对oakProjection这些东西加以更新等遇到再添加 by Xc
fn && fn.call(this, prevProps, prevState);
return [2 /*return*/];
}
});
});
};
OakComponentWrapper.prototype.render = function () {
var _this = this;

View File

@ -23,58 +23,56 @@ function getQuery(url, properties) {
query = parseUrl.query;
}
var query2 = {};
if (properties) {
for (var k in query) {
if (properties[k]) {
var type = typeof properties[k] === 'function' ? properties[k] : properties[k].type;
switch (type) {
case Number: {
Object.assign(query2, (_a = {},
_a[k] = Number(query[k]),
_a));
break;
}
case Boolean: {
Object.assign(query2, (_b = {},
_b[k] = Boolean(query[k]),
_b));
break;
}
case Array:
case Object: {
Object.assign(query2, (_c = {},
_c[k] = JSON.parse(query[k]),
_c));
break;
}
default: {
Object.assign(query2, (_d = {},
_d[k] = query[k],
_d));
}
for (var k in query) {
if (properties && properties[k]) {
var type = typeof properties[k] === 'function' ? properties[k] : properties[k].type;
switch (type) {
case Number: {
Object.assign(query2, (_a = {},
_a[k] = Number(query[k]),
_a));
break;
}
case Boolean: {
Object.assign(query2, (_b = {},
_b[k] = Boolean(query[k]),
_b));
break;
}
case Array:
case Object: {
Object.assign(query2, (_c = {},
_c[k] = JSON.parse(query[k]),
_c));
break;
}
default: {
Object.assign(query2, (_d = {},
_d[k] = query[k],
_d));
}
}
else {
switch (k) {
case 'oakIsPicker':
case 'enablePullDownRefresh': {
Object.assign(query2, (_e = {},
_e[k] = Boolean(query[k]),
_e));
break;
}
case 'oakFilters':
case 'oakSorters': {
Object.assign(query2, (_f = {},
_f[k] = JSON.parse(query[k]),
_f));
break;
}
default: {
Object.assign(query2, (_g = {},
_g[k] = query[k],
_g));
}
}
else {
switch (k) {
case 'oakIsPicker':
case 'enablePullDownRefresh': {
Object.assign(query2, (_e = {},
_e[k] = Boolean(query[k]),
_e));
break;
}
case 'oakFilters':
case 'oakSorters': {
Object.assign(query2, (_f = {},
_f[k] = JSON.parse(query[k]),
_f));
break;
}
default: {
Object.assign(query2, (_g = {},
_g[k] = query[k],
_g));
}
}
}

9
lib/types/Page.d.ts vendored
View File

@ -38,7 +38,7 @@ interface ComponentOption<ED extends EntityDict & BaseEntityDict, T extends keyo
'#name'?: string;
}>;
formData?: (options: {
data: IsList extends true ? RowSelected<ED, T, Proj>[] : RowSelected<ED, T, Proj>;
data: IsList extends true ? RowSelected<ED, T, Proj>[] : RowSelected<ED, T, Proj> | undefined;
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
}) => Promise<FormedData>;
@ -79,6 +79,7 @@ export declare type OakComponentOption<ED extends EntityDict & BaseEntityDict, T
show?(): void;
hide?(): void;
};
actions?: ED[T]['Action'][];
observers: Record<string, (...args: any[]) => any>;
}> & Partial<{
wechatMp: {
@ -94,6 +95,8 @@ export declare type OakComponentProperties = {
oakFrom: StringConstructor;
oakParentEntity: StringConstructor;
enablePullDownRefresh: BooleanConstructor;
oakAutoUnmount: BooleanConstructor;
oakActions: ArrayConstructor;
};
export declare type OakListComponentProperties = {
oakFilters: ObjectConstructor;
@ -135,6 +138,7 @@ export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntity
setMessage: (data: MessageProps) => void;
consumeMessage: () => MessageProps | undefined;
reRender: (extra?: Record<string, any>) => Promise<void>;
getFreshValue: (path?: string) => Promise<ED[keyof ED]['Schema'][] | ED[keyof ED]['Schema'] | undefined>;
navigateTo: <T2 extends keyof ED>(options: {
url: string;
} & OakNavigateToParameters<ED, T2>, state?: Record<string, any>, disableNamespace?: boolean) => Promise<void>;
@ -147,7 +151,7 @@ export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntity
cleanOperation: () => void;
t(key: string, params?: object): string;
callPicker: (attr: string, params: Record<string, any>) => void;
execute: () => Promise<ED[T]['Operation'][]>;
execute: (operation?: ED[T]['Operation']) => Promise<ED[T]['Operation'][]>;
checkOperation: (ntity: T, action: ED[T]['Action'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]) => Promise<boolean>;
tryExecute: () => Promise<void>;
refresh: (extra?: any) => Promise<void>;
@ -195,6 +199,7 @@ export declare type OakComponentData<ED extends EntityDict & BaseEntityDict, T e
oakEntity: T;
oakIsReady: boolean;
oakFullpath: string;
oakLegalActions?: ED[T]['Action'][];
};
export declare type MakeOakComponent<ED extends EntityDict & BaseEntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>> = <T extends keyof ED, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption>(options: OakComponentOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>) => React.ComponentType<any>;
export {};

View File

@ -123,6 +123,7 @@ export class Cache<
await this.cacheStore!.operate(entity, cloneDeep(operation), context, {
dontCollect: true,
dontCreateOper: true,
dontCreateModi: true,
});
}
await context.rollback();
@ -178,7 +179,7 @@ export class Cache<
{
dontCollect: true,
dontCreateOper: true,
blockTrigger: true,
dontCreateModi: true,
}
);
}

View File

@ -31,7 +31,8 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
protected loadingMore: boolean;
protected executing: boolean;
protected operations: Operation<ED, T>[];
protected modiIds: string[]; // 对象所关联的modi的id
protected modies: BaseEntityDict['modi']['OpSchema'][]; // 对象所关联的modi
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>,
projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>),
@ -46,7 +47,7 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
this.loadingMore = false;
this.executing = false;
this.operations = [];
this.modiIds = [];
this.modies = [];
}
getEntity() {
@ -60,12 +61,12 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
/**
* modi
*/
getModiIds(child: Node<ED, keyof ED, Cxt, AD>): string[] {
getModies(child: Node<ED, keyof ED, Cxt, AD>): BaseEntityDict['modi']['OpSchema'][] {
const childPath = this.getChildPath(child);
if (childPath.includes(':')) {
const { modiIds } = this;
if (childPath.includes(':next')) {
const { modies } = this;
// 如果是需要modi的路径在这里应该就可以返回了目前应该不存在modi嵌套modi
return modiIds;
return modies;
}
const { toModi } = this.schema[this.entity];
if (toModi) {
@ -73,7 +74,7 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
return [];
}
if (this.parent) {
return this.parent.getModiIds(this);
return this.parent.getModies(this);
}
return [];
}
@ -160,22 +161,40 @@ function mergeOperationData<ED extends EntityDict & BaseEntityDict, T extends ke
assert(!result);
}
else if (rel instanceof Array) {
// 这种情况还不是很清楚,感觉不太可能跑的到 by Xc
assert(false);
/* const [entity2] = rel;
const {
index,
eliminated,
} = findOperationToMerge(entity2, schema, from[attr] as any, into[attr] as any);
if (!index) {
(into[attr] as any).push(from[attr]);
/**
* list要合并list就可以了list相交的case
* $extraFile$XXX:1 $extraFile$XXX:2
*/
// (into[attr] as unknown as ED[keyof ED]['Operation'][]).push(...(from[attr] as unknown as ED[keyof ED]['Operation'][]));
const [entity2] = rel;
const mergeInner = (item: ED[keyof ED]['Operation']) => {
const {
index,
eliminated,
} = findOperationToMerge(entity2, schema, item, into[attr] as any);
if (!index) {
(into[attr] as any).push(item);
}
else {
const result2 = mergeOperationOper(entity2, schema, item, index);
if (result2) {
pull(into[attr] as any, index);
}
}
for (const eli of eliminated) {
pull((into[attr] as unknown as ED[keyof ED]['Operation'][]), eli);
}
};
if (from[attr] instanceof Array) {
for (const operation of from[attr] as unknown as ED[keyof ED]['Operation'][]) {
mergeInner(operation);
}
}
else {
const result2 = mergeOperationOper(entity2, schema, from[attr] as any, index);
if (result2) {
pull(from[attr] as any, index);
}
} */
assert(false); // 前台感觉是跑不出这个case的
mergeInner(from[attr] as unknown as ED[keyof ED]['Operation']);
}
}
else {
into[attr] = from[attr];
@ -202,33 +221,20 @@ function mergeOperationOper<ED extends EntityDict & BaseEntityDict, T extends ke
if (action === into.action) {
switch (action) {
case 'create': {
/**
* merge两个create动作singlearray
* array和single并存的case
*/
if (dataTo instanceof Array) {
if (data instanceof Array) {
data.forEach(
ele => assert(ele.id)
);
dataTo.push(...data);
}
else {
assert(data.id);
dataTo.push(data as ED[T]['CreateSingle']['data']);
}
}
else if (!(data instanceof Array) && !data.id) {
// 特殊情况其实就是单次create
mergeOperationData(entity, schema, data, dataTo);
assert (data instanceof Array);
data.forEach(
ele => assert(ele.id)
);
dataTo.push(...data);
}
else {
const data3 = [dataTo] as ED[T]['CreateMulti']['data'];
if (data instanceof Array) {
data3.push(...data);
}
else {
data3.push(data as ED[T]['CreateSingle']['data']);
}
Object.assign(into, {
data: data3,
});
assert(!(data instanceof Array));
mergeOperationData(entity, schema, data, dataTo);
}
return false;
}
@ -313,14 +319,19 @@ function findOperationToMerge<ED extends EntityDict & BaseEntityDict, T extends
} {
const { action, filter } = from;
const eliminated: ED[T]['Operation'][] = [];
if (action === 'create') {
// action不可能和当前已经的某个动作发生merge
return {
index: undefined,
eliminated,
};
}
for (const toOperation of existed) {
if (action === toOperation.action) {
switch (action) {
case 'create': {
return {
index: toOperation,
eliminated,
};
// 两个create不可能merge如果是many to one则不用走到这里判断
break;
}
default: {
// update/remove只合并filter完全相同的项
@ -717,19 +728,8 @@ class ListNode<
}
// 如果本结点是在modi路径上需要将modi更新之后再得到后项
const modiIds = this.parent ? this.parent.getModiIds(this) : [];
const operations = modiIds.map(
ele => ({
entity: 'modi',
operation: {
action: 'apply',
data: {},
filter: {
id: ele,
},
}
})
) as Array<{
const modies = this.parent ? this.parent.getModies(this) : [];
const operations = createOperationsFromModies(modies) as Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}>;
@ -1084,23 +1084,12 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
} */
async getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>> {
async getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']> | undefined> {
const projection = typeof this.projection === 'function' ? await this.projection() : this.projection;
// 如果本结点是在modi路径上需要将modi更新之后再得到后项
const modiIds = this.parent ? this.parent.getModiIds(this) : [];
const operations = modiIds.map(
ele => ({
entity: 'modi',
operation: {
action: 'apply',
data: {},
filter: {
id: ele,
},
}
})
) as Array<{
const modies = this.parent ? this.parent.getModies(this) : [];
const operations = createOperationsFromModies(modies) as Array<{
entity: keyof ED;
operation: ED[keyof ED]['Operation'];
}>;
@ -1109,19 +1098,21 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
if (operation?.oper.action === 'create') {
id = (operation.oper.data as ED[T]['CreateSingle']['data']).id;
}
operations.push(...this.operations.map(
ele => ({
entity: this.entity,
operation: ele.oper,
})
));
const { result } = await this.cache.tryRedoOperationsThenSelect(this.entity, {
data: projection,
filter: {
id,
} as any,
}, operations);
return result[0];
if (id) {
operations.push(...this.operations.map(
ele => ({
entity: this.entity,
operation: ele.oper,
})
));
const { result } = await this.cache.tryRedoOperationsThenSelect(this.entity, {
data: projection,
filter: {
id,
} as any,
}, operations);
return result[0];
}
}
@ -1183,9 +1174,8 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
}
else {
// singleNode上应当有且只有一个operation无论什么情况
const [current] = this.operations;
Object.assign(current.oper.data, oper.data);
mergeOperationTrigger(operation, current);
const result = mergeOperationOper(this.entity, this.schema, oper, this.operations[0].oper);
assert(!result);
}
this.setDirty();
}
@ -1314,7 +1304,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
// 对于modi对象在此缓存
if (this.schema[this.entity].toModi) {
const { modi$entity } = value;
this.modiIds = (modi$entity as Array<{ id: string }>).map(ele => ele.id);
this.modies = modi$entity as Array<BaseEntityDict['modi']['OpSchema']>;
}
this.loading = false;
}
@ -1457,6 +1447,10 @@ export class RunningTree<
} = options;
let node: ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD>;
const { parent, path } = analyzePath(fullPath);
if (this.findNode(fullPath)) {
return;
}
const parentNode = parent ? this.findNode(parent) : undefined;
const projectionShape =
typeof projection === 'function' ? await projection() : projection;
@ -1500,6 +1494,9 @@ export class RunningTree<
let node = this.root[paths[0]];
let iter = 1;
while (iter < paths.length && node) {
if (!node) {
return;
}
const childPath = paths[iter];
iter++;
node = node.getChild(childPath)!;
@ -1545,17 +1542,17 @@ export class RunningTree<
}
isLoading(path: string) {
const node = this.findNode(path);
const node = this.findNode(path)!;
return node.isLoading();
}
isLoadingMore(path: string) {
const node = this.findNode(path);
const node = this.findNode(path)!;
return node.isLoadingMore();
}
isExecuting(path: string) {
const node = this.findNode(path);
const node = this.findNode(path)!;
return node.isExecuting();
}
@ -1726,17 +1723,20 @@ export class RunningTree<
}
async tryExecute(path: string) {
const node = this.findNode(path);
const node = this.findNode(path)!;
const operations = await node.composeOperations();
if (operations) {
if (operations && operations.length > 0) {
return await this.cache.tryRedoOperations(node.getEntity(), operations);
}
return false;
}
@Action
async execute(path: string) {
const node = this.findNode(path);
async execute(path: string, operation?: ED[keyof ED]['Operation']) {
const node = this.findNode(path)!;
if (operation) {
await node.addOperation(operation);
}
assert(node.isDirty());
node.setExecuting(true);
@ -1764,7 +1764,7 @@ export class RunningTree<
@Action
clean(path: string) {
const node = this.findNode(path);
const node = this.findNode(path)!;
node.clean();
}

View File

@ -128,6 +128,9 @@ export async function onPathSet<
else if (oakId) {
await features.runningTree.setId(oakPath2, oakId);
}
else if (oakEntity || entity) {
this.reRender();
}
else {
// 啥都没有也要为了oakFullpath刷新一次
this.setState({
@ -198,6 +201,28 @@ export async function reRender<
Object.assign(data, {
oakAllowExecuting,
});
const actions: ED[T]['Action'][] = this.props.oakActions || option.actions;
if (actions && actions.length > 0) {
assert(this.props.oakId); // actions必须配合id来使用
const testResult = await Promise.all(
actions.map(
async ele => ({
action: ele,
result: await this.checkOperation(this.state.oakEntity, ele, { id: this.props.oakId }, ['user', 'row']),
})
)
);
const oakLegalActions = testResult.filter(
ele => ele.result
).map(
ele => ele.action
);
Object.assign(data, {
oakLegalActions,
});
}
this.setState(data);
} else {
const data: Record<string, any> = formData
@ -252,7 +277,7 @@ export async function execute<
T extends keyof ED,
Cxt extends Context<ED>>(
this: ComponentFullThisType<ED, T, Cxt>,
path?: string) {
operation?: ED[T]['Operation']) {
if (this.state.oakExecuting) {
throw new Error('请仔细设计按钮状态,不要允许重复点击!');
}
@ -261,10 +286,10 @@ export async function execute<
oakExecuting: true,
});
try {
const fullpath = path
/* const fullpath = path
? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath;
const result = await this.features.runningTree.execute(fullpath);
: this.state.oakFullpath; */
const result = await this.features.runningTree.execute(this.state.oakFullpath, operation);
this.setState({
oakExecuting: false,
})
@ -277,13 +302,19 @@ export async function execute<
if (err instanceof OakUserException) {
if (err instanceof OakInputIllegalException) {
const attrs = err.getAttributes();
const entity = err.getEntity();
const message = err.message;
this.setState({
/* this.setState({
oakFocused: {
attr: attrs[0],
message,
},
oakExecuting: false,
}); */
const attrNames = attrs.map(attr => this.t(`${entity}:attr.${attr}`)).filter(ele => !!ele);
this.setMessage({
type: 'error',
content: attrNames.length > 0 ? `${attrNames.join(',')}${message}` : message,
});
throw err;
}

View File

@ -261,16 +261,22 @@ abstract class OakComponentBase<
return callPicker.call(this as any, attr, params);
}
execute() {
return execute.call(this as any);
execute(operation?: ED[T]['Operation']) {
return execute.call(this as any, operation);
}
getFreshValue(path?: string) {
const path2 = path? `${this.state.oakFullpath}.${path}` : this.state.oakFullpath;
return this.features.runningTree.getFreshValue(path2) as Promise<ED[keyof ED]['Schema'][] | ED[keyof ED]['Schema'] | undefined>;
}
checkOperation(entity: T, action: ED[T]['Action'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]) {
return this.features.cache.checkOperation(entity, action, filter, checkerTypes);
}
tryExecute() {
return this.features.runningTree.tryExecute(this.state.oakFullpath);
tryExecute(path?: string) {
const path2 = path ? `${this.state.oakFullpath}.${path}` : this.state.oakFullpath;
return this.features.runningTree.tryExecute(path2);
}
refresh() {
@ -617,18 +623,18 @@ export function createComponent<
}
componentWillUnmount() {
this.state.oakFullpath && this.features.runningTree.destroyNode(this.state.oakFullpath);
this.state.oakFullpath && (this.iAmThePage() || this.props.oakAutoUnmount) && this.features.runningTree.destroyNode(this.state.oakFullpath);
lifetimes?.detached && lifetimes.detached.call(this);
this.unsubscribe();
this.unregisterPageScroll();
}
componentDidUpdate(prevProps: Record<string, any>, prevState: Record<string, any>) {
async componentDidUpdate(prevProps: Record<string, any>, prevState: Record<string, any>) {
if (!prevProps.oakPath && this.props.oakPath) {
this.onPathSet();
await this.onPathSet();
}
if (this.props.oakId !== prevProps.oakId) {
this.setId(this.props.oakId);
await this.setId(this.props.oakId);
}
// todo 这里似乎还可能对oakProjection这些东西加以更新等遇到再添加 by Xc

View File

@ -54,7 +54,7 @@ interface ComponentOption<
'#name'?: string;
}>;
formData?: (options: {
data: IsList extends true ? RowSelected<ED, T, Proj>[] : RowSelected<ED, T, Proj>;
data: IsList extends true ? RowSelected<ED, T, Proj>[] : RowSelected<ED, T, Proj> | undefined;
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
}) => Promise<FormedData>;
@ -163,6 +163,7 @@ export type OakComponentOption<
show?(): void;
hide?(): void;
};
actions?: ED[T]['Action'][];
observers: Record<string, (...args: any[]) => any>;
}> &
Partial<{
@ -182,6 +183,8 @@ export type OakComponentProperties = {
oakFrom: StringConstructor;
oakParentEntity: StringConstructor;
enablePullDownRefresh: BooleanConstructor;
oakAutoUnmount: BooleanConstructor;
oakActions: ArrayConstructor;
};
export type OakListComponentProperties = {
@ -230,6 +233,7 @@ export type OakCommonComponentMethods<
setMessage: (data: MessageProps) => void;
consumeMessage: () => MessageProps | undefined;
reRender: (extra?: Record<string, any>) => Promise<void>;
getFreshValue: (path?: string) => Promise<ED[keyof ED]['Schema'][] | ED[keyof ED]['Schema'] | undefined>;
navigateTo: <T2 extends keyof ED>(
options: { url: string } & OakNavigateToParameters<ED, T2>,
state?: Record<string, any>,
@ -248,7 +252,7 @@ export type OakCommonComponentMethods<
t(key: string, params?: object): string;
callPicker: (attr: string, params: Record<string, any>) => void;
execute: () => Promise<ED[T]['Operation'][]>;
execute: (operation?: ED[T]['Operation']) => Promise<ED[T]['Operation'][]>;
checkOperation: (ntity: T, action: ED[T]['Action'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]) => Promise<boolean>;
tryExecute: () => Promise<void>;
refresh: (extra?: any) => Promise<void>;
@ -313,6 +317,7 @@ export type OakComponentData<
oakEntity: T;
oakIsReady: boolean;
oakFullpath: string;
oakLegalActions?: ED[T]['Action'][];
};
export type MakeOakComponent<