This commit is contained in:
Xu Chang 2022-05-27 09:46:58 +08:00
commit 6aa4189cfc
10 changed files with 239 additions and 137 deletions

View File

@ -16,6 +16,7 @@ declare abstract class Node<ED extends EntityDict, T extends keyof ED, Cxt exten
private beforeExecute?;
private afterExecute?;
abstract onCachSync(opRecords: OpRecord<ED>[]): Promise<void>;
abstract refreshValue(): void;
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>, action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data']);
getEntity(): T;
setUpdateData(attr: string, value: any): void;
@ -43,6 +44,7 @@ declare class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Co
private pagination;
private projectionShape;
onCachSync(records: OpRecord<ED>[]): Promise<void>;
refreshValue(): void;
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), projectionShape: ED[T]['Selection']['data'], parent?: Node<ED, keyof ED, Cxt, AD>, action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data'], filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], pagination?: Pagination);
getChild(path: string): SingleNode<ED, T, Cxt, AD>;
getChildren(): SingleNode<ED, T, Cxt, AD>[];
@ -61,7 +63,7 @@ declare class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Co
addNamedSorter(sorter: NamedSorterItem<ED, T>): void;
removeNamedSorter(sorter: NamedSorterItem<ED, T>): void;
removeNamedSorterByName(name: string): void;
getValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>[];
getFreshValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>[];
getAction(): "update" | ED[T]["Action"];
composeOperation(action?: string, realId?: boolean): Promise<DeduceOperation<ED[T]['Schema']> | DeduceOperation<ED[T]['Schema']>[] | undefined>;
refresh(scene: string): Promise<void>;
@ -72,6 +74,7 @@ declare class ListNode<ED extends EntityDict, T extends keyof ED, Cxt extends Co
declare class SingleNode<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>> extends Node<ED, T, Cxt, AD> {
private id?;
private value?;
private freshValue?;
private children;
onCachSync(records: OpRecord<ED>[]): Promise<void>;
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>, projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), projectionShape: ED[T]['Selection']['data'], parent?: Node<ED, keyof ED, Cxt, AD>, action?: ED[T]['Action'], updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data']);
@ -80,13 +83,14 @@ declare class SingleNode<ED extends EntityDict, T extends keyof ED, Cxt extends
[K: string]: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
};
removeChild(path: string): void;
refreshValue(): void;
setValue(value: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']>): void;
updateValue(value: SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>): void;
getValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>;
getFreshValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>;
getAction(): "create" | "update" | ED[T]["Action"];
composeOperation(action2?: string, realId?: boolean): Promise<import("oak-domain/lib/types").DeduceCreateMultipleOperation<ED[T]["Schema"]> | DeduceUpdateOperation<ED[T]["Schema"]> | undefined>;
refresh(scene: string): Promise<void>;
resetUpdateData(): void;
setForeignKey(attr: string, id: string): Promise<void>;
}
export declare type CreateNodeOptions<ED extends EntityDict, T extends keyof ED> = {
path: string;
@ -115,12 +119,12 @@ export declare class RunningTree<ED extends EntityDict, Cxt extends Context<ED>,
destroyNode(path: string): void;
setStorageSchema(schema: StorageSchema<ED>): void;
private applyOperation;
getValue(path: string): Promise<(SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]> | undefined)[]>;
getFreshValue(path: string): Promise<SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]>[]>;
isDirty(path: string): boolean;
private setUpdateDataInner;
setUpdateData(path: string, attr: string, value: any): Promise<void>;
setAction<T extends keyof ED>(path: string, action: ED[T]['Action']): Promise<void>;
setForeignKey(path: string, id: string): Promise<void>;
setForeignKey(parent: string, attr: string, id: string): Promise<void>;
refresh(path: string): Promise<void>;
getNamedFilters<T extends keyof ED>(path: string): NamedFilterItem<ED, keyof ED>[];
getNamedFilterByName<T extends keyof ED>(path: string, name: string): NamedFilterItem<ED, keyof ED> | undefined;

View File

@ -47,6 +47,7 @@ class Node {
setUpdateData(attr, value) {
(0, lodash_1.set)(this.updateData, attr, value);
this.setDirty();
this.refreshValue();
}
getUpdateData() {
return this.updateData;
@ -54,6 +55,7 @@ class Node {
setMultiUpdateData(updateData) {
(0, lodash_1.assign)(this.updateData, updateData);
this.setDirty();
this.refreshValue();
}
setDirty() {
if (!this.dirty) {
@ -66,6 +68,7 @@ class Node {
setAction(action) {
this.action = action;
this.setDirty();
this.refreshValue();
}
isDirty() {
return this.dirty;
@ -145,7 +148,7 @@ class ListNode extends Node {
}
}
if (createdIds.length > 0 || removeIds) {
const currentIds = this.children.map(ele => ele.getValue().id);
const currentIds = this.children.map(ele => ele.getFreshValue().id);
const filter = (0, filter_1.combineFilters)([{
id: {
$in: currentIds.concat(createdIds),
@ -169,6 +172,8 @@ class ListNode extends Node {
this.setValue(value);
}
}
refreshValue() {
}
constructor(entity, schema, cache, projection, projectionShape, parent, action, updateData, filters, sorters, pagination) {
super(entity, schema, cache, projection, parent, action, updateData);
this.projectionShape = projectionShape;
@ -181,7 +186,14 @@ class ListNode extends Node {
getChild(path) {
const idx = parseInt(path, 10);
(0, assert_1.default)(typeof idx === 'number');
return this.children[idx];
if (idx < this.children.length) {
return this.children[idx];
}
else {
const idx2 = idx - this.children.length;
// assert(idx2 < this.newBorn.length); // 在删除结点时可能还是会跑到
return this.newBorn[idx2];
}
}
getChildren() {
return this.children;
@ -200,15 +212,11 @@ class ListNode extends Node {
this.children.splice(idx, 1);
}
setValue(value) {
this.children = [];
value.forEach((ele, idx) => {
if (this.children[idx]) {
this.children[idx].setValue(ele);
}
else {
const node = new SingleNode(this.entity, this.schema, this.cache, this.projection, this.projectionShape, this);
this.children[idx] = node;
node.setValue(ele);
}
const node = new SingleNode(this.entity, this.schema, this.cache, this.projection, this.projectionShape, this);
this.children[idx] = node;
node.setValue(ele);
});
}
getNamedFilters() {
@ -279,9 +287,18 @@ class ListNode extends Node {
this.sorters.splice(fIndex, 1);
}
}
getValue() {
const value = this.children.map(ele => ele.getValue());
return value;
getFreshValue() {
const value = this.children.map(ele => ele.getFreshValue());
if (this.isDirty()) {
const action = this.action || 'update';
if (action === 'remove') {
return []; // 这个可能跑到吗?
}
return value.map(ele => (0, lodash_1.assign)({}, ele, this.updateData));
}
else {
return value;
}
}
getAction() {
(0, assert_1.default)(this.dirty);
@ -379,6 +396,7 @@ class ListNode extends Node {
class SingleNode extends Node {
id;
value;
freshValue;
children;
async onCachSync(records) {
let needReGetValue = false;
@ -439,7 +457,7 @@ class SingleNode extends Node {
id: this.id,
}
}, 'onCacheSync');
this.updateValue(value);
this.setValue(value);
}
}
constructor(entity, schema, cache, projection, projectionShape, parent, action, updateData) {
@ -508,6 +526,20 @@ class SingleNode extends Node {
removeChild(path) {
(0, lodash_1.unset)(this.children, path);
}
refreshValue() {
const action = this.action || (this.isDirty() ? 'update' : '');
if (!action) {
this.freshValue = this.value;
}
else {
if (action === 'remove') {
this.freshValue = undefined;
}
else {
this.freshValue = (0, lodash_1.assign)({}, this.value, this.updateData);
}
}
}
setValue(value) {
for (const attr in this.children) {
const node = this.children[attr];
@ -531,22 +563,16 @@ class SingleNode extends Node {
}
this.id = value.id;
this.value = value;
this.refreshValue();
}
updateValue(value) {
if (!this.value) {
this.value = {};
}
(0, lodash_1.assign)(this.value, value);
// todo可能的一对多和多对一的子结点上的处理
}
getValue() {
const value = this.value ? (0, lodash_1.cloneDeep)(this.value) : {};
getFreshValue() {
const freshValue = this.freshValue ? (0, lodash_1.cloneDeep)(this.freshValue) : {};
for (const k in this.children) {
(0, lodash_1.assign)(value, {
[k]: this.children[k].getValue(),
(0, lodash_1.assign)(freshValue, {
[k]: this.children[k].getFreshValue(),
});
}
return value;
return freshValue;
}
getAction() {
return this.action || (this.id ? 'update' : 'create');
@ -597,6 +623,35 @@ class SingleNode extends Node {
for (const attr in this.children) {
this.children[attr].resetUpdateData();
}
this.refreshValue();
}
async setForeignKey(attr, id) {
const rel = this.judgeRelation(attr);
let subEntity;
if (rel === 2) {
this.setMultiUpdateData({
entity: attr,
entityId: id,
});
subEntity = attr;
}
else {
(0, assert_1.default)(typeof rel === 'string');
this.setUpdateData(`${attr}Id`, id);
subEntity = rel;
}
// 如果修改了外键且对应的外键上有子结点在这里把子结点的value更新掉
if (this.children[attr]) {
const proj = typeof this.projection === 'function' ? await this.projection() : this.projection;
const subProj = proj[attr];
const [value] = await this.cache.get(subEntity, {
data: subProj,
filter: {
id,
},
}, 'SingleNode:setForeignKey');
this.children[attr].setValue(value);
}
}
}
class RunningTree extends Feature_1.Feature {
@ -810,14 +865,9 @@ class RunningTree extends Feature_1.Feature {
}
}
}
async getValue(path) {
async getFreshValue(path) {
const node = this.findNode(path);
let value = node.getValue();
if (node.isDirty()) {
const operation = await node.composeOperation();
const projection = await node.getProjection();
value = (await this.applyOperation(node.getEntity(), (0, lodash_1.cloneDeep)(value), operation, projection, path));
}
let value = node.getFreshValue();
return value instanceof Array ? value : [value];
}
isDirty(path) {
@ -851,20 +901,10 @@ class RunningTree extends Feature_1.Feature {
const node = this.findNode(path);
node.setAction(action);
}
async setForeignKey(path, id) {
throw new Error('method not implemented');
const node = this.findNode(path);
const parent = node.getParent();
const attr = path.slice(path.lastIndexOf('.') + 1);
const rel = (0, relation_1.judgeRelation)(this.schema, parent.getEntity(), attr);
if (rel === 2) {
parent.setUpdateData('entity', node.getEntity());
parent.setUpdateData('entityId', id);
}
else {
(0, assert_1.default)(typeof rel === 'string');
parent.setUpdateData(`${attr}Id`, id);
}
async setForeignKey(parent, attr, id) {
const parentNode = this.findNode(parent);
(0, assert_1.default)(parentNode instanceof SingleNode);
parentNode.setForeignKey(attr, id);
}
async refresh(path) {
const node = this.findNode(path);
@ -1017,7 +1057,7 @@ class RunningTree extends Feature_1.Feature {
const parentNode = this.findNode(parent);
const node = parentNode.getChild(path);
(0, assert_1.default)(parentNode instanceof ListNode && node instanceof SingleNode); // 现在应该不可能remove一个list吧未来对list的处理还要细化
if (node.getValue().id) {
if (node.getFreshValue().id) {
// 如果有id说明是删除数据
await this.getAspectProxy().operate({
entity: node.getEntity(),
@ -1025,7 +1065,7 @@ class RunningTree extends Feature_1.Feature {
action: 'remove',
data: {},
filter: {
id: node.getValue().id,
id: node.getFreshValue().id,
},
}
}, parent);

1
lib/index.d.ts vendored
View File

@ -4,3 +4,4 @@ export * from './types/Feature';
export * from './types/ExceptionRoute';
export { BasicFeatures } from './features';
export * from './features/cache';
export * from './features/upload';

View File

@ -1,7 +1,11 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
@ -16,3 +20,4 @@ Object.defineProperty(exports, "InitializeWechatMp", { enumerable: true, get: fu
__exportStar(require("./types/Feature"), exports);
__exportStar(require("./types/ExceptionRoute"), exports);
__exportStar(require("./features/cache"), exports);
__exportStar(require("./features/upload"), exports);

View File

@ -1,7 +1,11 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];

View File

@ -64,7 +64,7 @@ declare type OakComponentMethods<ED extends EntityDict, T extends keyof ED> = {
subscribed?: () => void;
subscribe: () => void;
unsubscribe: () => void;
reRender: (extra?: any) => Promise<void>;
reRender: (extra?: Record<string, any>) => Promise<void>;
pushNode: (path?: string, options?: Pick<CreateNodeOptions<ED, keyof ED>, 'updateData' | 'beforeExecute' | 'afterExecute'>) => void;
removeNode: (parent: string, path: string) => void;
setUpdateData: (attr: string, input: any) => void;

View File

@ -49,9 +49,9 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
newOakActions: Array,
},
methods: {
async reRender() {
async reRender(extra) {
if (this.data.oakFullpath) {
const $rows = await features.runningTree.getValue(this.data.oakFullpath);
const $rows = await features.runningTree.getFreshValue(this.data.oakFullpath);
const data = await formData.call(this, $rows, features);
for (const k in data) {
if (data[k] === undefined) {
@ -79,6 +79,9 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
oakLegalActions,
});
}
if (extra) {
(0, lodash_1.assign)(data, extra);
}
this.setData(data);
}
},
@ -352,9 +355,9 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
};
}));
}
const path2 = oakParent ? `${oakParent}:${oakPath || options.path}` : oakPath || options.path;
const node = await features.runningTree.createNode({
path: oakPath || options.path,
parent: oakParent,
path: path2,
entity: (oakEntity || options.entity),
isList,
isPicker: oakIsPicker,
@ -364,10 +367,10 @@ function createPageOptions(options, doSubscribe, features, exceptionRouterDict)
sorters,
id: oakId,
});
const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
// const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
this.setData({
oakEntity: node.getEntity(),
oakFullpath,
oakFullpath: path2,
oakFrom,
newOakActions: oakActions && JSON.parse(oakActions).length > 0 ? JSON.parse(oakActions) : options.actions || [],
});
@ -433,9 +436,9 @@ function createComponentOptions(options, features, doSubscribe, exceptionRouterD
this.subscribed = undefined;
}
},
async reRender() {
async reRender(extra) {
if (this.data.oakFullpath) {
const $rows = await features.runningTree.getValue(this.data.oakFullpath);
const $rows = await features.runningTree.getFreshValue(this.data.oakFullpath);
const data = await formData.call(this, $rows, features);
for (const k in data) {
if (data[k] === undefined) {
@ -463,6 +466,9 @@ function createComponentOptions(options, features, doSubscribe, exceptionRouterD
oakLegalActions,
});
} */
if (extra) {
(0, lodash_1.assign)(data, extra);
}
this.setData(data);
}
},
@ -472,7 +478,9 @@ function createComponentOptions(options, features, doSubscribe, exceptionRouterD
if (path2 && parent2) {
const oakFullpath2 = `${parent2}.${path2}`;
if (oakFullpath2 !== this.data.oakFullpath) {
this.data.oakFullpath = oakFullpath2;
this.setData({
oakFullpath: oakFullpath2,
});
this.reRender();
}
}
@ -576,7 +584,10 @@ function createComponentOptions(options, features, doSubscribe, exceptionRouterD
async ready() {
const { oakPath, oakParent } = this.data;
if (oakParent && oakPath) {
this.data.oakFullpath = `${oakParent}.${oakPath}`;
const oakFullpath = `${oakParent}.${oakPath}`;
this.setData({
oakFullpath,
});
this.reRender();
}
},

View File

@ -26,6 +26,8 @@ abstract class Node<ED extends EntityDict, T extends keyof ED, Cxt extends Conte
abstract onCachSync(opRecords: OpRecord<ED>[]): Promise<void>;
abstract refreshValue(): void;
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>, action?: ED[T]['Action'],
@ -49,6 +51,7 @@ abstract class Node<ED extends EntityDict, T extends keyof ED, Cxt extends Conte
setUpdateData(attr: string, value: any) {
set(this.updateData, attr, value);
this.setDirty();
this.refreshValue();
}
getUpdateData() {
@ -58,6 +61,7 @@ abstract class Node<ED extends EntityDict, T extends keyof ED, Cxt extends Conte
setMultiUpdateData(updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data']) {
assign(this.updateData, updateData);
this.setDirty();
this.refreshValue();
}
setDirty() {
@ -72,6 +76,7 @@ abstract class Node<ED extends EntityDict, T extends keyof ED, Cxt extends Conte
setAction(action: ED[T]['Action']) {
this.action = action;
this.setDirty();
this.refreshValue();
}
isDirty() {
@ -170,7 +175,7 @@ class ListNode<ED extends EntityDict,
}
if (createdIds.length > 0 || removeIds) {
const currentIds = this.children.map(
ele => ele.getValue().id
ele => ele.getFreshValue().id
) as string[];
const filter = combineFilters([{
@ -179,17 +184,19 @@ class ListNode<ED extends EntityDict,
}
}, ...(this.filters).map(ele => ele.filter)]);
const sorterss = await Promise.all(this.sorters.map(
async (ele) => {
const { sorter } = ele;
if (typeof sorter === 'function') {
return await sorter();
const sorterss = await Promise.all(
this.sorters.map(
async (ele) => {
const { sorter } = ele;
if (typeof sorter === 'function') {
return await sorter();
}
else {
return sorter;
}
}
else {
return sorter;
}
}
));
)
);
const projection = typeof this.projection === 'function' ? await this.projection() : this.projection;
const value = await this.cache.get(this.entity, {
data: projection as any,
@ -200,6 +207,10 @@ class ListNode<ED extends EntityDict,
}
}
refreshValue(): void {
}
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>,
projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>),
projectionShape: ED[T]['Selection']['data'],
@ -337,11 +348,23 @@ class ListNode<ED extends EntityDict,
}
}
getValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>[] {
getFreshValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>[] {
const value = this.children.map(
ele => ele.getValue()
ele => ele.getFreshValue()
);
return value;
if (this.isDirty()) {
const action = this.action || 'update';
if (action === 'remove') {
return []; // 这个可能跑到吗?
}
return value.map(
ele => assign({}, ele, this.updateData)
);
}
else {
return value;
}
}
getAction() {
@ -459,6 +482,7 @@ class SingleNode<ED extends EntityDict,
AD extends Record<string, Aspect<ED, Cxt>>> extends Node<ED, T, Cxt, AD> {
private id?: string;
private value?: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']>;
private freshValue?: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']>;
private children: {
[K: string]: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
@ -523,7 +547,7 @@ class SingleNode<ED extends EntityDict,
id: this.id,
}
} as any, 'onCacheSync');
this.updateValue(value);
this.setValue(value);
}
}
@ -606,6 +630,21 @@ class SingleNode<ED extends EntityDict,
unset(this.children, path);
}
refreshValue() {
const action = this.action || (this.isDirty() ? 'update' : '');
if (!action) {
this.freshValue = this.value;
}
else {
if (action === 'remove') {
this.freshValue = undefined;
}
else {
this.freshValue = assign({}, this.value, this.updateData);
}
}
}
setValue(value: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']>) {
for (const attr in this.children) {
const node = this.children[attr];
@ -630,27 +669,19 @@ class SingleNode<ED extends EntityDict,
}
this.id = value.id as string;
this.value = value;
this.refreshValue();
}
updateValue(value: SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>) {
if (!this.value) {
this.value = {} as SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>;
}
assign(this.value, value);
// todo可能的一对多和多对一的子结点上的处理
}
getValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']> {
const value = this.value ? cloneDeep(this.value) : {} as SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>;
getFreshValue(): SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']> {
const freshValue = this.freshValue ? cloneDeep(this.freshValue) : {} as SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>;
for (const k in this.children) {
assign(value, {
[k]: this.children[k].getValue(),
assign(freshValue, {
[k]: this.children[k].getFreshValue(),
});
}
return value;
return freshValue;
}
getAction() {
@ -708,6 +739,38 @@ class SingleNode<ED extends EntityDict,
for (const attr in this.children) {
this.children[attr].resetUpdateData();
}
this.refreshValue();
}
async setForeignKey(attr: string, id: string) {
const rel = this.judgeRelation(attr);
let subEntity: string;
if (rel === 2) {
this.setMultiUpdateData({
entity: attr,
entityId: id,
} as any);
subEntity = attr;
}
else {
assert(typeof rel === 'string');
this.setUpdateData(`${attr}Id`, id);
subEntity = rel;
}
// 如果修改了外键且对应的外键上有子结点在这里把子结点的value更新掉
if (this.children[attr]) {
const proj = typeof this.projection === 'function' ? await this.projection() : this.projection;
const subProj = proj[attr];
const [value] = await this.cache.get(subEntity, {
data: subProj,
filter: {
id,
} as any,
}, 'SingleNode:setForeignKey');
(<SingleNode<ED, keyof ED, Cxt, AD>>this.children[attr]).setValue(value);
}
}
}
@ -981,20 +1044,11 @@ export class RunningTree<ED extends EntityDict, Cxt extends Context<ED>, AD exte
}
}
async getValue(path: string) {
async getFreshValue(path: string) {
const node = this.findNode(path);
if (node) {
let value: ReturnType<typeof node.getValue> | undefined = node.getValue();
let value = node.getFreshValue();
if (node.isDirty()) {
const operation = await node.composeOperation();
const projection = await node.getProjection();
value = (await this.applyOperation(node.getEntity(), cloneDeep(value), operation!, projection, path));
}
return value instanceof Array ? value : [value];
}
return [];
return value instanceof Array ? value : [value];
}
isDirty(path: string) {
@ -1034,21 +1088,11 @@ export class RunningTree<ED extends EntityDict, Cxt extends Context<ED>, AD exte
}
@Action
async setForeignKey(path: string, id: string) {
throw new Error('method not implemented');
const node = this.findNode(path);
const parent = node.getParent()!;
const attr = path.slice(path.lastIndexOf('.') + 1);
const rel = judgeRelation(this.schema!, parent.getEntity(), attr);
async setForeignKey(parent: string, attr: string, id: string) {
const parentNode = this.findNode(parent);
assert (parentNode instanceof SingleNode);
if (rel === 2) {
parent.setUpdateData('entity', node.getEntity());
parent.setUpdateData('entityId', id);
}
else {
assert(typeof rel === 'string');
parent.setUpdateData(`${attr}Id`, id);
}
parentNode.setForeignKey(attr, id);
}
@Action
@ -1234,7 +1278,7 @@ export class RunningTree<ED extends EntityDict, Cxt extends Context<ED>, AD exte
const node = parentNode.getChild(path);
assert(parentNode instanceof ListNode && node instanceof SingleNode); // 现在应该不可能remove一个list吧未来对list的处理还要细化
if (node.getValue().id) {
if (node.getFreshValue().id) {
// 如果有id说明是删除数据
await this.getAspectProxy().operate({
entity: node.getEntity() as string,
@ -1242,7 +1286,7 @@ export class RunningTree<ED extends EntityDict, Cxt extends Context<ED>, AD exte
action: 'remove',
data: {},
filter: {
id: node.getValue().id,
id: node.getFreshValue().id,
},
}
}, parent);

View File

@ -225,7 +225,7 @@ function createPageOptions<ED extends EntityDict,
methods: {
async reRender(extra) {
if (this.data.oakFullpath) {
const $rows = await features.runningTree.getValue(this.data.oakFullpath);
const $rows = await features.runningTree.getFreshValue(this.data.oakFullpath);
const data = await formData.call(this, $rows as any, features);
for (const k in data) {
if (data[k] === undefined) {
@ -573,9 +573,9 @@ function createPageOptions<ED extends EntityDict,
}
));
}
const path2 = oakParent ? `${oakParent}:${oakPath || options.path}` : oakPath || options.path;
const node = await features.runningTree.createNode({
path: oakPath || options.path,
parent: oakParent,
path: path2,
entity: (oakEntity || options.entity) as T,
isList,
isPicker: oakIsPicker,
@ -585,10 +585,10 @@ function createPageOptions<ED extends EntityDict,
sorters,
id: oakId,
});
const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
// const oakFullpath = oakParent ? `${oakParent}.${oakPath || options.path}` : oakPath || options.path;
this.setData({
oakEntity: node.getEntity(),
oakFullpath,
oakFullpath: path2,
oakFrom,
newOakActions: oakActions && JSON.parse(oakActions).length > 0 ? JSON.parse(oakActions) : options.actions || [],
});
@ -684,7 +684,7 @@ function createComponentOptions<ED extends EntityDict,
async reRender(extra) {
if (this.data.oakFullpath) {
const $rows = await features.runningTree.getValue(this.data.oakFullpath);
const $rows = await features.runningTree.getFreshValue(this.data.oakFullpath);
const data = await formData.call(this, $rows as any, features);
for (const k in data) {
if (data[k] === undefined) {

View File

@ -5,10 +5,3 @@ type A = {
areaId: string;
area?: number;
}
const a: A = {
areaId: 'ddd',
area: {
bb: 1,
},
}