diff --git a/lib/features/runningTree.d.ts b/lib/features/runningTree.d.ts index 0805bf76..377bcb63 100644 --- a/lib/features/runningTree.d.ts +++ b/lib/features/runningTree.d.ts @@ -121,7 +121,7 @@ declare class ListNode, FrontCxt extends SyncContext, AD extends CommonAspectDict> extends Node { - private id; + private id?; private children; private operation?; constructor(entity: T, schema: StorageSchema, cache: Cache, authDict: AuthDefDict, projection?: ED[T]['Selection']['data'] | (() => Promise), parent?: SingleNode | ListNode | VirtualNode, path?: string, id?: string, actions?: ActionDef[] | (() => ActionDef[]), cascadeActions?: () => { @@ -133,14 +133,13 @@ declare class SingleNode | ListNode; setId(id: string): void; unsetId(): void; - getId(): string; + getId(): string | undefined; getChildren(): { [K: string]: SingleNode | ListNode; }; addChild(path: string, node: SingleNode | ListNode): void; removeChild(path: string): void; getFreshValue(context?: FrontCxt): Partial | undefined; - isCreation(): boolean; doBeforeTrigger(): Promise; doAfterTrigger(): Promise; create(data: Partial>, beforeExecute?: () => Promise, afterExecute?: () => Promise): void; @@ -232,7 +231,7 @@ export declare class RunningTree(path: string, pageSize: number): void; setCurrentPage(path: string, currentPage: number): void; getNamedFilters(path: string): NamedFilterItem[]; @@ -253,7 +252,6 @@ export declare class RunningTree(path: string, action?: ED[T]['Action']): Promise<{ result: Awaited>; message: string | null | undefined; diff --git a/lib/features/runningTree.js b/lib/features/runningTree.js index b82d39ba..908023f9 100644 --- a/lib/features/runningTree.js +++ b/lib/features/runningTree.js @@ -1054,8 +1054,7 @@ var SingleNode = /** @class */ (function (_super) { this.publish(); }; SingleNode.prototype.unsetId = function () { - this.create({}); - this.id = this.operation.operation.data.id; + this.id = undefined; this.publish(); }; // 最好用getFreshValue取值 @@ -1085,12 +1084,6 @@ var SingleNode = /** @class */ (function (_super) { return result[0]; } }; - SingleNode.prototype.isCreation = function () { - var _a; - var operations = this.composeOperations(); - // 如果是create,一定在第一个 - return !!(operations && ((_a = operations[0]) === null || _a === void 0 ? void 0 : _a.operation.action) === 'create'); - }; SingleNode.prototype.doBeforeTrigger = function () { var _a; return tslib_1.__awaiter(this, void 0, void 0, function () { @@ -1161,6 +1154,7 @@ var SingleNode = /** @class */ (function (_super) { }; SingleNode.prototype.create = function (data, beforeExecute, afterExecute) { var id = (0, uuid_1.generateNewId)(); + (0, assert_1.assert)(!this.id && !this.dirty, 'create前要保证singleNode为空'); this.operation = { operation: { id: (0, uuid_1.generateNewId)(), @@ -1170,6 +1164,7 @@ var SingleNode = /** @class */ (function (_super) { beforeExecute: beforeExecute, afterExecute: afterExecute, }; + this.id = id; this.setDirty(); }; SingleNode.prototype.update = function (data, action, beforeExecute, afterExecute) { @@ -1238,10 +1233,16 @@ var SingleNode = /** @class */ (function (_super) { if (childOperations) { if (child instanceof SingleNode) { (0, assert_1.assert)(childOperations.length === 1); - (0, assert_1.assert)(!operation.data[ele2]); // 多对一的子结点不应该有多项 - Object.assign(operation.data, (_a = {}, - _a[ele2] = childOperations[0].operation, - _a)); + if (!operation.data[ele2]) { + Object.assign(operation.data, (_a = {}, + _a[ele2] = childOperations[0].operation, + _a)); + } + else { + // 目前应该只允许一种情况,就是父create,子update + (0, assert_1.assert)(operation.data[ele].action === 'create' && childOperations[0].operation.action === 'update'); + Object.assign(operation.data[ele].data, childOperations[0].operation.data); + } } else { (0, assert_1.assert)(child instanceof ListNode); @@ -1305,11 +1306,12 @@ var SingleNode = /** @class */ (function (_super) { return projection; }; SingleNode.prototype.refresh = function () { + var _a; return tslib_1.__awaiter(this, void 0, void 0, function () { var projection, filter, err_2; var _this = this; - return tslib_1.__generator(this, function (_a) { - switch (_a.label) { + return tslib_1.__generator(this, function (_b) { + switch (_b.label) { case 0: // SingleNode如果是ListNode的子结点,则不必refresh(优化,ListNode有义务负责子层对象的数据) if (this.parent && this.parent instanceof ListNode && this.parent.getEntity() === this.getEntity()) { @@ -1317,7 +1319,7 @@ var SingleNode = /** @class */ (function (_super) { return [2 /*return*/]; } // 如果是新建,也不用refresh - if (this.isCreation()) { + if (((_a = this.operation) === null || _a === void 0 ? void 0 : _a.operation.action) === 'create') { return [2 /*return*/]; } projection = this.getProjection(undefined, true); @@ -1325,9 +1327,9 @@ var SingleNode = /** @class */ (function (_super) { if (!(projection && filter)) return [3 /*break*/, 4]; this.setLoading(true); this.publish(); - _a.label = 1; + _b.label = 1; case 1: - _a.trys.push([1, 3, , 4]); + _b.trys.push([1, 3, , 4]); return [4 /*yield*/, this.cache.refresh(this.entity, { data: projection, filter: filter, @@ -1341,10 +1343,10 @@ var SingleNode = /** @class */ (function (_super) { _this.setLoading(false); })]; case 2: - _a.sent(); + _b.sent(); return [3 /*break*/, 4]; case 3: - err_2 = _a.sent(); + err_2 = _b.sent(); this.setLoading(false); throw err_2; case 4: return [2 /*return*/]; @@ -2026,11 +2028,6 @@ var RunningTree = /** @class */ (function (_super) { var operations = node.composeOperations(); return operations; }; - RunningTree.prototype.isCreation = function (path) { - var node = this.findNode(path); - (0, assert_1.assert)(node instanceof SingleNode); - return node.isCreation(); - }; RunningTree.prototype.execute = function (path, action) { return tslib_1.__awaiter(this, void 0, void 0, function () { var node, operations, entities, result, err_3; diff --git a/lib/page.mp.js b/lib/page.mp.js index dae8ed63..0cd6d1ac 100644 --- a/lib/page.mp.js +++ b/lib/page.mp.js @@ -398,18 +398,18 @@ var oakBehavior = Behavior({ unsetId: function () { return this.features.runningTree.unsetId(this.state.oakFullpath); }, - isCreation: function (path) { - var path2 = path - ? "".concat(this.state.oakFullpath, ".").concat(path) - : this.state.oakFullpath; - return this.features.runningTree.isCreation(path2); - }, update: function (data, action, beforeExecute, afterExecute, path) { var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) : this.state.oakFullpath; return this.features.runningTree.update(path2, data, action, beforeExecute, afterExecute); }, + create: function (data, beforeExecute, afterExecute, path) { + var path2 = path + ? "".concat(this.state.oakFullpath, ".").concat(path) + : this.state.oakFullpath; + return this.features.runningTree.create(path2, data, beforeExecute, afterExecute); + }, remove: function (beforeExecute, afterExecute, path) { var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) diff --git a/lib/page.web.js b/lib/page.web.js index 28702a55..6c0ddc49 100644 --- a/lib/page.web.js +++ b/lib/page.web.js @@ -163,18 +163,18 @@ var OakComponentBase = /** @class */ (function (_super) { /* create(data: Omit, beforeExecute?: () => Promise, afterExecute?: () => Promise) { this.features.runningTree.create(this.state.oakFullpath, data, beforeExecute, afterExecute); } */ - OakComponentBase.prototype.isCreation = function (path) { - var path2 = path - ? "".concat(this.state.oakFullpath, ".").concat(path) - : this.state.oakFullpath; - return this.features.runningTree.isCreation(path2); - }; OakComponentBase.prototype.update = function (data, action, beforeExecute, afterExecute, path) { var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) : this.state.oakFullpath; this.features.runningTree.update(path2, data, action, beforeExecute, afterExecute); }; + OakComponentBase.prototype.create = function (data, beforeExecute, afterExecute, path) { + var path2 = path + ? "".concat(this.state.oakFullpath, ".").concat(path) + : this.state.oakFullpath; + this.features.runningTree.create(path2, data, beforeExecute, afterExecute); + }; OakComponentBase.prototype.remove = function (beforeExecute, afterExecute, path) { var path2 = path ? "".concat(this.state.oakFullpath, ".").concat(path) @@ -536,12 +536,12 @@ function createComponent(option, features) { update: function (data, action, beforeExecute, afterExecute, path) { return _this.update(data, action, beforeExecute, afterExecute, path); }, + create: function (data, beforeExecute, afterExecute, path) { + return _this.create(data, beforeExecute, afterExecute, path); + }, remove: function (beforeExecute, afterExecute, path) { return _this.remove(beforeExecute, afterExecute, path); }, - isCreation: function (path) { - return _this.isCreation(path); - } }); if (methods) { var _loop_1 = function (m) { diff --git a/lib/types/Page.d.ts b/lib/types/Page.d.ts index 48900a87..fd4f6677 100644 --- a/lib/types/Page.d.ts +++ b/lib/types/Page.d.ts @@ -200,9 +200,9 @@ export declare type OakSingleComponentMethods void; unsetId: () => void; getId: () => string | undefined; + create: (data: Omit, beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; update: (data: ED[T]['Update']['data'], action?: ED[T]['Action'], beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; remove: (beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; - isCreation: (path?: string) => boolean; }; export declare type OakListComponentMethods = { loadMore: () => Promise; @@ -260,7 +260,7 @@ export declare type OakListComoponetData, FrontCxt extends SyncContext, AD extends Record>, FD extends Record> = (options: OakComponentOption) => (props: ReactComponentProps) => React.ReactElement; export declare type WebComponentCommonMethodNames = 'setNotification' | 'setMessage' | 'navigateTo' | 'navigateBack' | 'redirectTo' | 'clean' | 't' | 'execute' | 'refresh' | 'setDisablePulldownRefresh' | 'aggregate' | 'checkOperation'; export declare type WebComponentListMethodNames = 'loadMore' | 'setFilters' | 'addNamedFilter' | 'removeNamedFilter' | 'removeNamedFilterByName' | 'setNamedSorters' | 'addNamedSorter' | 'removeNamedSorter' | 'removeNamedSorterByName' | 'setPageSize' | 'setCurrentPage' | 'addItem' | 'removeItem' | 'updateItem' | 'resetItem' | 'recoverItem'; -export declare type WebComponentSingleMethodNames = 'update' | 'remove' | 'isCreation'; +export declare type WebComponentSingleMethodNames = 'update' | 'remove' | 'create'; export declare type WebComponentProps = { methods: TMethod & OakCommonComponentMethods & OakListComponentMethods & OakSingleComponentMethods; data: TData & OakComponentData & (IsList extends true ? OakListComoponetData : {}); diff --git a/src/features/runningTree.ts b/src/features/runningTree.ts index 9d24e1a8..46799a07 100644 --- a/src/features/runningTree.ts +++ b/src/features/runningTree.ts @@ -1066,7 +1066,7 @@ class SingleNode, FrontCxt extends SyncContext, AD extends CommonAspectDict> extends Node { - private id: string; + private id?: string; private children: { [K: string]: SingleNode | ListNode; }; @@ -1153,8 +1153,7 @@ class SingleNode { if (this.operation?.beforeExecute) { @@ -1221,6 +1214,7 @@ class SingleNode>, beforeExecute?: () => Promise, afterExecute?: () => Promise) { const id = generateNewId(); + assert(!this.id && !this.dirty, 'create前要保证singleNode为空'); this.operation = { operation: { id: generateNewId(), @@ -1230,6 +1224,7 @@ class SingleNode(path: string, action?: ED[T]['Action']) { const node = this.findNode(path)!; if (action) { diff --git a/src/page.mp.ts b/src/page.mp.ts index 7c8fa9ea..7f33b7a6 100644 --- a/src/page.mp.ts +++ b/src/page.mp.ts @@ -585,13 +585,6 @@ const oakBehavior = Behavior< return this.features.runningTree.unsetId(this.state.oakFullpath); }, - isCreation(path?: string) { - const path2 = path - ? `${this.state.oakFullpath}.${path}` - : this.state.oakFullpath; - return this.features.runningTree.isCreation(path2); - }, - update(data, action, beforeExecute, afterExecute, path) { const path2 = path ? `${this.state.oakFullpath}.${path}` @@ -604,6 +597,19 @@ const oakBehavior = Behavior< afterExecute ); }, + + create(data, beforeExecute, afterExecute, path) { + const path2 = path + ? `${this.state.oakFullpath}.${path}` + : this.state.oakFullpath; + return this.features.runningTree.create( + path2, + data, + beforeExecute, + afterExecute + ); + }, + remove(beforeExecute, afterExecute, path) { const path2 = path ? `${this.state.oakFullpath}.${path}` diff --git a/src/page.web.tsx b/src/page.web.tsx index 1d70bb26..1b9de9c0 100644 --- a/src/page.web.tsx +++ b/src/page.web.tsx @@ -78,7 +78,7 @@ abstract class OakComponentBase< name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption - ) {} + ) { } sub(type: string, callback: Function) { this.features.eventBus.sub(type, callback); @@ -301,13 +301,6 @@ abstract class OakComponentBase< this.features.runningTree.create(this.state.oakFullpath, data, beforeExecute, afterExecute); } */ - isCreation(path?: string) { - const path2 = path - ? `${this.state.oakFullpath}.${path}` - : this.state.oakFullpath; - return this.features.runningTree.isCreation(path2); - } - update( data: ED[T]['Update']['data'], action?: ED[T]['Action'], @@ -327,6 +320,23 @@ abstract class OakComponentBase< ); } + create( + data: Omit, + beforeExecute?: () => Promise, + afterExecute?: () => Promise, + path?: string + ) { + const path2 = path + ? `${this.state.oakFullpath}.${path}` + : this.state.oakFullpath; + this.features.runningTree.create( + path2, + data, + beforeExecute, + afterExecute + ); + } + remove( beforeExecute?: () => Promise, afterExecute?: () => Promise, @@ -682,7 +692,7 @@ export function createComponent< > & { getRender: () => React.ComponentType; }; - + if (option.observers) { console.error('observers即将废弃(已经没有效果),请使用listeners重写'); } @@ -815,12 +825,15 @@ export function createComponent< update: (data: ED[T]['Update']['data'], action: ED[T]['Action'], beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => { return this.update(data, action, beforeExecute, afterExecute, path); }, + create: (data: Omit, + beforeExecute?: () => Promise, + afterExecute?: () => Promise, + path?: string) => { + return this.create(data, beforeExecute, afterExecute, path); + }, remove: (beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => { return this.remove(beforeExecute, afterExecute, path); }, - isCreation: (path?: string) => { - return this.isCreation(path); - } } as Record); if (methods) { diff --git a/src/types/Page.ts b/src/types/Page.ts index d8d0bc2c..83b37d87 100644 --- a/src/types/Page.ts +++ b/src/types/Page.ts @@ -381,10 +381,9 @@ export type OakSingleComponentMethods void; unsetId: () => void; getId: () => string | undefined; - // create: (data: Omit, beforeExecute?: () => Promise, afterExecute?: () => Promise) => void; + create: (data: Omit, beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; update: (data: ED[T]['Update']['data'], action?: ED[T]['Action'], beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; remove: (beforeExecute?: () => Promise, afterExecute?: () => Promise, path?: string) => void; - isCreation: (path?: string) => boolean; } export type OakListComponentMethods = { @@ -489,7 +488,7 @@ export type WebComponentListMethodNames = 'loadMore' | 'setFilters' | 'addNamedF | 'addNamedSorter' | 'removeNamedSorter' | 'removeNamedSorterByName' | 'setPageSize' | 'setCurrentPage' | 'addItem' | 'removeItem' | 'updateItem' | 'resetItem' | 'recoverItem'; // 暴露给single组件的方法 -export type WebComponentSingleMethodNames = 'update' | 'remove' | 'isCreation'; +export type WebComponentSingleMethodNames = 'update' | 'remove' | 'create'; export type WebComponentProps< ED extends EntityDict & BaseEntityDict,