runningTree的小问题

This commit is contained in:
Xu Chang 2022-11-01 11:31:09 +08:00
parent 4505938b1e
commit f412afd2a9
6 changed files with 422 additions and 273 deletions

View File

@ -38,7 +38,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 | string[] | 2 | 1;
judgeRelation(entity: keyof ED, attr: string): string | 0 | 1 | 2 | string[];
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

@ -42,7 +42,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict, T extends ke
setExecuting(executing: boolean): void;
getParent(): Node<ED, keyof ED, Cxt, AD> | VirtualNode | undefined;
protected getProjection(): Promise<ED[T]["Selection"]["data"]>;
protected judgeRelation(attr: string): string | 0 | string[] | 2 | 1;
protected judgeRelation(attr: string): string | 0 | 1 | 2 | string[];
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;
}

View File

@ -1402,7 +1402,7 @@ var SingleNode = /** @class */ (function (_super) {
};
SingleNode.prototype.getFreshValue = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var projection, modies, _a, operations, filter, createOper, result;
var projection, modies, _a, operations, filter, createOper, parent_1, result;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
@ -1426,6 +1426,10 @@ var SingleNode = /** @class */ (function (_super) {
id: createOper.oper.data.id
};
}
parent_1 = this.parent;
if (parent_1 instanceof ListNode || parent_1 instanceof SingleNode) {
filter = parent_1.getParentFilter(this);
}
}
if (!filter) return [3 /*break*/, 5];
operations.push.apply(operations, tslib_1.__spreadArray([], tslib_1.__read(this.operations.map(function (ele) { return ({
@ -1554,10 +1558,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, result;
var _g, _h;
return tslib_1.__generator(this, function (_j) {
switch (_j.label) {
var operation, id, _a, _b, _c, result;
var _d;
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
case 0:
if (this.id) {
if (oper.action === 'create') {
@ -1583,26 +1587,25 @@ var SingleNode = /** @class */ (function (_super) {
// 处理一下create
this.operations.push(operation);
if (!(oper.action === 'create')) return [3 /*break*/, 2];
_b = (_a = Object).assign;
_c = [oper.data];
_g = {};
return [4 /*yield*/, generateNewId()];
case 1:
_b.apply(_a, _c.concat([(_g.id = _j.sent(),
_g)]));
_j.label = 2;
id = _e.sent();
Object.assign(oper.data, {
id: id,
});
_e.label = 2;
case 2:
_e = (_d = Object).assign;
_f = [oper];
_h = {};
_b = (_a = Object).assign;
_c = [oper];
_d = {};
return [4 /*yield*/, generateNewId()];
case 3:
_e.apply(_d, _f.concat([(_h.id = _j.sent(), _h)]));
_b.apply(_a, _c.concat([(_d.id = _e.sent(), _d)]));
return [3 /*break*/, 5];
case 4:
result = mergeOperationOper(this.entity, this.schema, oper, this.operations[0].oper);
(0, assert_1.assert)(!result);
_j.label = 5;
_e.label = 5;
case 5:
this.setDirty();
return [2 /*return*/];
@ -1866,13 +1869,12 @@ var SingleNode = /** @class */ (function (_super) {
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.id) {
return [2 /*return*/];
}
return [4 /*yield*/, this.getFreshValue()];
case 0: return [4 /*yield*/, this.getFreshValue()];
case 1:
value = (_b.sent());
if (!value) {
return [2 /*return*/];
}
for (key in this.children) {
if (childNode === this.children[key]) {
sliceIdx = key.indexOf(':');
@ -2284,14 +2286,14 @@ var RunningTree = /** @class */ (function (_super) {
var node = this.findNode(path);
if (node) {
var childPath = path.slice(path.lastIndexOf('.') + 1);
var parent_1 = node.getParent();
if (parent_1 instanceof SingleNode) {
parent_1.removeChild(childPath);
var parent_2 = node.getParent();
if (parent_2 instanceof SingleNode) {
parent_2.removeChild(childPath);
}
else if (parent_1 instanceof ListNode) {
parent_1.removeChild(childPath);
else if (parent_2 instanceof ListNode) {
parent_2.removeChild(childPath);
}
else if (!parent_1) {
else if (!parent_2) {
(0, assert_1.assert)(this.root.hasOwnProperty(path));
(0, lodash_1.unset)(this.root, path);
}

View File

@ -19,119 +19,187 @@ var OakProperties = {
oakAutoUnmount: Boolean,
oakDisablePulldownRefresh: Boolean,
};
var oakBehavior = Behavior({
methods: {
iAmThePage: function () {
var pages = getCurrentPages();
if (pages[0] === this) {
return true;
}
return false;
},
subscribe: function () {
var _this = this;
this.subscribed = (0, Feature_1.subscribe)(function () { return _this.reRender(); });
},
unsubscribe: function () {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
},
setState: function (data, callback) {
var _this = this;
this.setData(data, function () {
_this.state = _this.data;
callback && callback.call(_this);
});
},
reRender: function () {
page_common_1.reRender.call(this, this.option);
},
onLoad: function (query) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, properties, path, assignProps, key, key;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = this.options, properties = _a.properties, path = _a.path;
assignProps = function (data, property, type) {
var _a;
if (data[property]) {
var value = data[property];
if (typeof data[property] === 'string' && type !== String) {
switch (type) {
case Boolean: {
value = new Boolean(data[property]);
break;
}
case Number: {
value = new Number(data[property]);
break;
}
case Object: {
value = JSON.parse(data[property]);
break;
}
default: {
(0, assert_1.default)(false);
}
}
}
Object.assign(_this.props, (_a = {},
_a[property] = value,
_a));
}
};
if (properties) {
for (key in properties) {
if (query[key]) {
assignProps(query, key, properties[key]);
}
else {
assignProps(this.data, key, properties[key]);
}
}
}
for (key in OakProperties) {
if (query[key]) {
assignProps(query, key, OakProperties[key]);
}
else {
assignProps(this.data, key, OakProperties[key]);
}
}
if (!(this.props.oakPath || (this.iAmThePage() && path))) return [3 /*break*/, 2];
return [4 /*yield*/, page_common_1.onPathSet.call(this, this.option)];
case 1:
_b.sent();
return [3 /*break*/, 3];
case 2:
this.reRender();
_b.label = 3;
case 3: return [2 /*return*/];
}
});
});
},
},
observers: {
oakPath: function (data) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!data) return [3 /*break*/, 2];
return [4 /*yield*/, page_common_1.onPathSet.call(this, this.option)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
}
},
pageLifetimes: {
show: function () {
var show = (this.options.lifetimes || {}).show;
this.subscribe();
this.reRender();
show && show.call(this);
},
hide: function () {
var hide = (this.options.lifetimes || {}).hide;
this.unsubscribe();
hide && hide.call(this);
}
},
lifetimes: {
created: function () {
var _this = this;
var setData = this.setData;
this.state = this.data;
this.setData = function (data, callback) {
setData.call(_this, data, function () {
_this.state = _this.data;
callback && callback.call(_this);
});
};
},
attached: function () {
var _a;
var attached = (this.options.lifetimes || {}).attached;
var i18nInstance = (0, i18n_1.getI18nInstanceWechatMp)();
if (i18nInstance) {
this.setState((_a = {},
_a[i18n_1.CURRENT_LOCALE_KEY] = i18nInstance.currentLocale,
_a[i18n_1.CURRENT_LOCALE_DATA] = i18nInstance.translations,
_a));
}
attached && attached.call(this);
},
detached: function () {
var detached = (this.options.lifetimes || {}).detached;
this.unsubscribe();
detached && detached.call(this);
},
ready: function () {
var ready = (this.options.lifetimes || {}).ready;
ready && ready.call(this);
},
moved: function () {
var moved = (this.options.lifetimes || {}).moved;
moved && moved.call(this);
},
error: function (err) {
var error = (this.options.lifetimes || {}).error;
error && error.call(this, err);
}
},
});
function createComponent(option, features) {
var path = option.path, data = option.data, properties = option.properties, methods = option.methods, lifetimes = option.lifetimes, observers = option.observers, actions = option.actions;
var _a = lifetimes || {}, attached = _a.attached, show = _a.show, hide = _a.hide, created = _a.created, detached = _a.detached, restLifetimes = tslib_1.__rest(_a, ["attached", "show", "hide", "created", "detached"]);
return Component({
behaviors: [oakBehavior],
data: Object.assign({}, data, {
oakFullpath: '',
}),
properties: Object.assign({}, properties, OakProperties),
methods: tslib_1.__assign({ iAmThePage: function () {
var pages = getCurrentPages();
if (pages[0] === this) {
return true;
}
return false;
}, subscribe: function () {
var _this = this;
this.subscribed = (0, Feature_1.subscribe)(function () { return _this.reRender(); });
}, unsubscribe: function () {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
}, setState: function (data, callback) {
var _this = this;
this.setData(data, function () {
_this.state = _this.data;
callback && callback.call(_this);
});
}, reRender: function () {
page_common_1.reRender.call(this, option);
}, onLoad: function (query) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var assignProps, key, key;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
assignProps = function (data, property, type) {
var _a;
if (data[property]) {
var value = data[property];
if (typeof data[property] === 'string' && type !== String) {
switch (type) {
case Boolean: {
value = new Boolean(data[property]);
break;
}
case Number: {
value = new Number(data[property]);
break;
}
case Object: {
value = JSON.parse(data[property]);
break;
}
default: {
(0, assert_1.default)(false);
}
}
}
Object.assign(_this.props, (_a = {},
_a[property] = value,
_a));
}
};
if (properties) {
for (key in properties) {
if (query[key]) {
assignProps(query, key, properties[key]);
}
else {
assignProps(this.data, key, properties[key]);
}
}
}
for (key in OakProperties) {
if (query[key]) {
assignProps(query, key, OakProperties[key]);
}
else {
assignProps(this.data, key, OakProperties[key]);
}
}
if (!(this.props.oakPath || (this.iAmThePage() && path))) return [3 /*break*/, 2];
return [4 /*yield*/, page_common_1.onPathSet.call(this, option)];
case 1:
_a.sent();
return [3 /*break*/, 3];
case 2:
this.reRender();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
});
} }, methods),
observers: {
oakPath: function (data) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!data) return [3 /*break*/, 2];
return [4 /*yield*/, page_common_1.onPathSet.call(this, option)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
}
},
methods: tslib_1.__assign({}, methods),
observers: tslib_1.__assign({}, observers),
pageLifetimes: {
show: function () {
this.subscribe();
@ -143,32 +211,13 @@ function createComponent(option, features) {
hide && hide.call(this);
}
},
lifetimes: tslib_1.__assign({ created: function () {
var _this = this;
var setData = this.setData;
this.state = this.data;
lifetimes: {
created: function () {
this.option = option;
this.features = features;
this.setData = function (data, callback) {
setData.call(_this, data, function () {
_this.state = _this.data;
callback && callback.call(_this);
});
};
created && created.call(this);
}, attached: function () {
var _a;
var i18nInstance = (0, i18n_1.getI18nInstanceWechatMp)();
if (i18nInstance) {
this.setState((_a = {},
_a[i18n_1.CURRENT_LOCALE_KEY] = i18nInstance.currentLocale,
_a[i18n_1.CURRENT_LOCALE_DATA] = i18nInstance.translations,
_a));
}
attached && attached.call(this);
}, detached: function () {
this.unsubscribe();
detached && detached.call(this);
} }, restLifetimes),
},
},
});
}
exports.createComponent = createComponent;

View File

@ -1169,6 +1169,12 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
id: createOper.oper.data.id
};
}
// 还可能是来自父级的外键
const { parent } = this;
if (parent instanceof ListNode || parent instanceof SingleNode) {
filter = parent.getParentFilter(this);
}
}
if (filter) {
operations.push(...this.operations.map(
@ -1238,8 +1244,9 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
// 处理一下create
this.operations.push(operation as Operation<ED, T>);
if (oper.action === 'create') {
const id = await generateNewId();
Object.assign(oper.data, {
id: await generateNewId(),
id,
});
}
Object.assign(oper, { id: await generateNewId() });
@ -1432,11 +1439,11 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
}
}
async getParentFilter<T2 extends keyof ED>(childNode: Node<ED, keyof ED, Cxt, AD>): Promise<ED[T2]['Selection']['filter'] | undefined> {
if (!this.id) {
async getParentFilter<T2 extends keyof ED>(childNode: Node<ED, keyof ED, Cxt, AD>): Promise<ED[T2]['Selection']['filter'] | undefined> {
const value = (await this.getFreshValue())!;
if (!value) {
return;
}
const value = (await this.getFreshValue())!;
for (const key in this.children) {
if (childNode === this.children[key]) {

View File

@ -38,6 +38,191 @@ const OakProperties = {
oakDisablePulldownRefresh: Boolean,
};
type EDD = EntityDict & BaseEntityDict;
type Cxt = Context<EntityDict & BaseEntityDict>;
type ADD = Record<string, Aspect<EDD, Cxt>>;
type FDD = Record<string, Feature>;
const oakBehavior = Behavior<
WechatMiniprogram.Component.DataOption,
WechatMiniprogram.Component.PropertyOption,
WechatMiniprogram.Component.MethodOption,
{
state: Record<string, any>;
props: {
oakId: string;
oakPath: string;
oakFilters: string;
oakSorters: string;
oakIsPicker: boolean;
oakParentEntity: string;
oakFrom: string;
oakActions: string;
oakAutoUnmount: boolean;
oakDisablePulldownRefresh: boolean;
} & Record<string, any>;
features: BasicFeatures<EDD, Cxt, ADD & CommonAspectDict<EDD, Cxt>> & FDD;
subscribed: (() => void) | undefined;
options: OakComponentOption<
EDD,
keyof EDD,
Cxt,
ADD,
FDD,
EDD[keyof EDD]['Selection']['data'],
Record<string, any>,
boolean,
Record<string, any>,
Record<string, any>,
Record<string, Function>
>
}>({
methods: {
iAmThePage() {
const pages = getCurrentPages();
if (pages[0] === this as any) {
return true;
}
return false;
},
subscribe() {
this.subscribed = FeactureSubscribe(() => this.reRender());
},
unsubscribe() {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
},
setState(data: Record<string, any>, callback: () => void) {
this.setData(data, () => {
this.state = this.data;
callback && callback.call(this);
});
},
reRender() {
reRender.call(this as any, this.option as any);
},
async onLoad(query: Record<string, any>) {
/**
* props传递数据
*
*/
const { properties, path } = this.options;
const assignProps = (data: Record<string, any>, property: string, type: String | Boolean | Number | Object) => {
if (data[property]) {
let value = data[property];
if (typeof data[property] === 'string' && type !== String) {
switch (type) {
case Boolean: {
value = new Boolean(data[property]);
break;
}
case Number: {
value = new Number(data[property]);
break;
}
case Object: {
value = JSON.parse(data[property]);
break;
}
default: {
assert(false);
}
}
}
Object.assign(this.props, {
[property]: value,
});
}
};
if (properties) {
for (const key in properties) {
if (query[key]) {
assignProps(query, key, properties[key]!);
}
else {
assignProps(this.data, key, properties[key]!);
}
}
}
for (const key in OakProperties) {
if (query[key]) {
assignProps(query, key, OakProperties[key as keyof typeof OakProperties]!);
}
else {
assignProps(this.data, key, OakProperties[key as keyof typeof OakProperties]!);
}
}
if (this.props.oakPath || (this.iAmThePage() && path)) {
await onPathSet.call(this as any, this.option as any);
}
else {
this.reRender();
}
},
},
observers: {
async oakPath(data) {
if (data) {
await onPathSet.call(this as any, this.option as any);
}
}
},
pageLifetimes: {
show() {
const { show } = this.options.lifetimes || {};
this.subscribe();
this.reRender();
show && show.call(this);
},
hide() {
const { hide } = this.options.lifetimes || {};
this.unsubscribe();
hide && hide.call(this);
}
},
lifetimes: {
created() {
const { setData } = this;
this.state = this.data;
this.setData = (data, callback) => {
setData.call(this, data, () => {
this.state = this.data;
callback && callback.call(this);
});
};
},
attached() {
const { attached } = this.options.lifetimes || {};
const i18nInstance = getI18nInstanceWechatMp();
if (i18nInstance) {
(this as any).setState({
[CURRENT_LOCALE_KEY]: i18nInstance.currentLocale,
[CURRENT_LOCALE_DATA]: i18nInstance.translations,
});
}
attached && attached.call(this);
},
detached() {
const { detached } = this.options.lifetimes || {};
this.unsubscribe();
detached && detached.call(this);
},
ready() {
const { ready } = this.options.lifetimes || {};
ready && ready.call(this);
},
moved() {
const { moved } = this.options.lifetimes || {};
moved && moved.call(this);
},
error(err: Error) {
const { error } = this.options.lifetimes || {};
error && error.call(this, err);
}
},
})
export function createComponent<
ED extends EntityDict & BaseEntityDict,
T extends keyof ED,
@ -97,102 +282,30 @@ export function createComponent<
} & Record<string, any>;
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
subscribed: (() => void) | undefined;
option: OakComponentOption<
ED,
T,
Cxt,
AD,
FD,
Proj,
FormedData,
IsList,
TData,
TProperty,
TMethod
>;
}>({
behaviors: [oakBehavior],
data: Object.assign({}, data, {
oakFullpath: '',
}),
properties: Object.assign({}, properties, OakProperties),
methods: {
iAmThePage() {
const pages = getCurrentPages();
if (pages[0] === this as any) {
return true;
}
return false;
},
subscribe() {
this.subscribed = FeactureSubscribe(() => this.reRender());
},
unsubscribe() {
if (this.subscribed) {
this.subscribed();
this.subscribed = undefined;
}
},
setState(data: Record<string, any>, callback: () => void) {
this.setData(data, () => {
this.state = this.data;
callback && callback.call(this);
});
},
reRender() {
reRender.call(this as any, option as any);
},
async onLoad(query: Record<string, any>) {
/**
* props传递数据
*
*/
const assignProps = (data: Record<string, any>, property: string, type: String | Boolean | Number | Object) => {
if (data[property]) {
let value = data[property];
if (typeof data[property] === 'string' && type !== String) {
switch (type) {
case Boolean: {
value = new Boolean(data[property]);
break;
}
case Number: {
value = new Number(data[property]);
break;
}
case Object: {
value = JSON.parse(data[property]);
break;
}
default: {
assert(false);
}
}
}
Object.assign(this.props, {
[property]: value,
});
}
};
if (properties) {
for (const key in properties) {
if (query[key]) {
assignProps(query, key, properties[key]!);
}
else {
assignProps(this.data, key, properties[key]!);
}
}
}
for (const key in OakProperties) {
if (query[key]) {
assignProps(query, key, OakProperties[key as keyof typeof OakProperties]!);
}
else {
assignProps(this.data, key, OakProperties[key as keyof typeof OakProperties]!);
}
}
if (this.props.oakPath || (this.iAmThePage() && path)) {
await onPathSet.call(this as any, option as any);
}
else {
this.reRender();
}
},
...methods,
},
observers: {
async oakPath(data) {
if (data) {
await onPathSet.call(this as any, option as any);
}
}
...observers,
},
pageLifetimes: {
show() {
@ -207,32 +320,10 @@ export function createComponent<
},
lifetimes: {
created() {
const { setData } = this;
this.state = this.data;
this.option = option;
this.features = features;
this.setData = (data, callback) => {
setData.call(this, data, () => {
this.state = this.data;
callback && callback.call(this);
});
};
created && created.call(this);
},
attached() {
const i18nInstance = getI18nInstanceWechatMp();
if (i18nInstance) {
(this as any).setState({
[CURRENT_LOCALE_KEY]: i18nInstance.currentLocale,
[CURRENT_LOCALE_DATA]: i18nInstance.translations,
});
}
attached && attached.call(this);
},
detached() {
this.unsubscribe();
detached && detached.call(this);
},
...restLifetimes,
},
})
});
}