新的架构和接口(web部分)
This commit is contained in:
parent
ec34d5972a
commit
d2f0dfe05d
|
|
@ -1,7 +1,7 @@
|
|||
import { EntityDict, OperateOption, OperationResult, OpRecord, SelectOption } from 'oak-domain/lib/types/Entity';
|
||||
import { StorageSchema } from "oak-domain/lib/types/Storage";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { Checker, Context } from 'oak-domain/lib/types';
|
||||
import { Checker, CheckerType, Context } from 'oak-domain/lib/types';
|
||||
import { TreeStore } from 'oak-memory-tree-store';
|
||||
export declare class CacheStore<ED extends EntityDict & BaseEntityDict, Cxt extends Context<ED>> extends TreeStore<ED, Cxt> {
|
||||
private executor;
|
||||
|
|
@ -10,6 +10,7 @@ export declare class CacheStore<ED extends EntityDict & BaseEntityDict, Cxt exte
|
|||
constructor(storageSchema: StorageSchema<ED>, contextBuilder: () => (store: CacheStore<ED, Cxt>) => Cxt, getFullDataFn?: () => any, resetInitialDataFn?: () => void);
|
||||
operate<T extends keyof ED, OP extends OperateOption>(entity: T, operation: ED[T]['Operation'], context: Cxt, option: OP): Promise<OperationResult<ED>>;
|
||||
sync(opRecords: Array<OpRecord<ED>>, context: Cxt): Promise<void>;
|
||||
check<T extends keyof ED>(entity: T, operation: ED[T]['Operation'], context: Cxt, checkerTypes?: CheckerType[]): Promise<void>;
|
||||
select<T extends keyof ED, S extends ED[T]['Selection'], OP extends SelectOption>(entity: T, selection: S, context: Cxt, option: OP): Promise<import("oak-domain/lib/types").SelectionResult<ED[T]["Schema"], S["data"]>>;
|
||||
registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ exports.CacheStore = void 0;
|
|||
var tslib_1 = require("tslib");
|
||||
var TriggerExecutor_1 = require("oak-domain/lib/store/TriggerExecutor");
|
||||
var oak_memory_tree_store_1 = require("oak-memory-tree-store");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var CacheStore = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(CacheStore, _super);
|
||||
function CacheStore(storageSchema, contextBuilder, getFullDataFn, resetInitialDataFn) {
|
||||
|
|
@ -99,6 +100,48 @@ var CacheStore = /** @class */ (function (_super) {
|
|||
});
|
||||
});
|
||||
};
|
||||
CacheStore.prototype.check = function (entity, operation, context, checkerTypes) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var action, checkers, checkers_1, checkers_1_1, checker, e_1_1;
|
||||
var e_1, _a;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
action = operation.action;
|
||||
checkers = this.executor.getCheckers(entity, action, checkerTypes);
|
||||
(0, assert_1.default)(context.getCurrentTxnId());
|
||||
if (!checkers) return [3 /*break*/, 8];
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
_b.trys.push([1, 6, 7, 8]);
|
||||
checkers_1 = tslib_1.__values(checkers), checkers_1_1 = checkers_1.next();
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
if (!!checkers_1_1.done) return [3 /*break*/, 5];
|
||||
checker = checkers_1_1.value;
|
||||
return [4 /*yield*/, checker.fn({ operation: operation }, context, {})];
|
||||
case 3:
|
||||
_b.sent();
|
||||
_b.label = 4;
|
||||
case 4:
|
||||
checkers_1_1 = checkers_1.next();
|
||||
return [3 /*break*/, 2];
|
||||
case 5: return [3 /*break*/, 8];
|
||||
case 6:
|
||||
e_1_1 = _b.sent();
|
||||
e_1 = { error: e_1_1 };
|
||||
return [3 /*break*/, 8];
|
||||
case 7:
|
||||
try {
|
||||
if (checkers_1_1 && !checkers_1_1.done && (_a = checkers_1.return)) _a.call(checkers_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
return [7 /*endfinally*/];
|
||||
case 8: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
CacheStore.prototype.select = function (entity, selection, context, option) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var autoCommit, result, err_3;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { EntityDict, OperateOption, SelectOption, OpRecord, Context, AspectWrapper, SelectionResult } from 'oak-domain/lib/types';
|
||||
import { EntityDict, OperateOption, SelectOption, OpRecord, Context, AspectWrapper, SelectionResult, CheckerType } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Feature } from '../types/Feature';
|
||||
|
|
@ -22,19 +22,20 @@ export declare class Cache<ED extends EntityDict & BaseEntityDict, Cxt extends C
|
|||
* @param operation
|
||||
* @returns
|
||||
*/
|
||||
testOperation<T extends keyof ED>(entity: T, operation: ED[T]['Operation']): Promise<boolean>;
|
||||
tryRedoOperations<T extends keyof ED>(entity: T, operations: ED[T]['Operation'][]): Promise<boolean>;
|
||||
checkOperation<T extends keyof ED>(entity: T, action: ED[T]['Action'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]): Promise<boolean>;
|
||||
/**
|
||||
* 尝试在cache中重做一些动作,然后选择重做后的数据(为了实现modi)
|
||||
* @param entity
|
||||
* @param selection
|
||||
* @param opers
|
||||
*/
|
||||
tryRedoOperations<T extends keyof ED, S extends ED[T]['Selection']>(entity: T, selection: S, opers: Array<{
|
||||
tryRedoOperationsThenSelect<T extends keyof ED, S extends ED[T]['Selection']>(entity: T, selection: S, opers: Array<{
|
||||
entity: keyof ED;
|
||||
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 | 1 | string[] | 2;
|
||||
judgeRelation(entity: keyof ED, attr: string): string | 0 | 2 | 1 | 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; };
|
||||
|
|
|
|||
|
|
@ -78,13 +78,11 @@ var Cache = /** @class */ (function (_super) {
|
|||
var result;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
(0, selection_1.reinforceSelection)(this.cacheStore.getSchema(), entity, selection);
|
||||
return [4 /*yield*/, this.getAspectWrapper().exec('count', {
|
||||
entity: entity,
|
||||
selection: selection,
|
||||
option: option,
|
||||
})];
|
||||
case 0: return [4 /*yield*/, this.getAspectWrapper().exec('count', {
|
||||
entity: entity,
|
||||
selection: selection,
|
||||
option: option,
|
||||
})];
|
||||
case 1:
|
||||
result = (_a.sent()).result;
|
||||
return [2 /*return*/, result];
|
||||
|
|
@ -121,9 +119,67 @@ var Cache = /** @class */ (function (_super) {
|
|||
* @param operation
|
||||
* @returns
|
||||
*/
|
||||
Cache.prototype.testOperation = function (entity, operation) {
|
||||
Cache.prototype.tryRedoOperations = function (entity, operations) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var context, err_1;
|
||||
var context, operations_1, operations_1_1, operation, e_1_1, err_1;
|
||||
var e_1, _a;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
context = this.contextBuilder();
|
||||
return [4 /*yield*/, context.begin()];
|
||||
case 1:
|
||||
_b.sent();
|
||||
_b.label = 2;
|
||||
case 2:
|
||||
_b.trys.push([2, 12, , 14]);
|
||||
_b.label = 3;
|
||||
case 3:
|
||||
_b.trys.push([3, 8, 9, 10]);
|
||||
operations_1 = tslib_1.__values(operations), operations_1_1 = operations_1.next();
|
||||
_b.label = 4;
|
||||
case 4:
|
||||
if (!!operations_1_1.done) return [3 /*break*/, 7];
|
||||
operation = operations_1_1.value;
|
||||
return [4 /*yield*/, this.cacheStore.operate(entity, operation, context, {
|
||||
dontCollect: true,
|
||||
dontCreateOper: true,
|
||||
})];
|
||||
case 5:
|
||||
_b.sent();
|
||||
_b.label = 6;
|
||||
case 6:
|
||||
operations_1_1 = operations_1.next();
|
||||
return [3 /*break*/, 4];
|
||||
case 7: return [3 /*break*/, 10];
|
||||
case 8:
|
||||
e_1_1 = _b.sent();
|
||||
e_1 = { error: e_1_1 };
|
||||
return [3 /*break*/, 10];
|
||||
case 9:
|
||||
try {
|
||||
if (operations_1_1 && !operations_1_1.done && (_a = operations_1.return)) _a.call(operations_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
return [7 /*endfinally*/];
|
||||
case 10: return [4 /*yield*/, context.rollback()];
|
||||
case 11:
|
||||
_b.sent();
|
||||
return [3 /*break*/, 14];
|
||||
case 12:
|
||||
err_1 = _b.sent();
|
||||
return [4 /*yield*/, context.rollback()];
|
||||
case 13:
|
||||
_b.sent();
|
||||
throw err_1;
|
||||
case 14: return [2 /*return*/, true];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
Cache.prototype.checkOperation = function (entity, action, filter, checkerTypes) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var context, operation, err_2;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
|
|
@ -131,26 +187,28 @@ var Cache = /** @class */ (function (_super) {
|
|||
return [4 /*yield*/, context.begin()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
operation = {
|
||||
action: action,
|
||||
filter: filter,
|
||||
data: {},
|
||||
};
|
||||
_a.label = 2;
|
||||
case 2:
|
||||
_a.trys.push([2, 5, , 7]);
|
||||
return [4 /*yield*/, this.cacheStore.operate(entity, operation, context, {
|
||||
dontCollect: true,
|
||||
dontCreateOper: true,
|
||||
})];
|
||||
return [4 /*yield*/, this.cacheStore.check(entity, operation, context, checkerTypes)];
|
||||
case 3:
|
||||
_a.sent();
|
||||
return [4 /*yield*/, context.rollback()];
|
||||
case 4:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 7];
|
||||
return [2 /*return*/, true];
|
||||
case 5:
|
||||
err_1 = _a.sent();
|
||||
err_2 = _a.sent();
|
||||
return [4 /*yield*/, context.rollback()];
|
||||
case 6:
|
||||
_a.sent();
|
||||
throw err_1;
|
||||
case 7: return [2 /*return*/, true];
|
||||
return [2 /*return*/, false];
|
||||
case 7: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -161,10 +219,10 @@ var Cache = /** @class */ (function (_super) {
|
|||
* @param selection
|
||||
* @param opers
|
||||
*/
|
||||
Cache.prototype.tryRedoOperations = function (entity, selection, opers) {
|
||||
Cache.prototype.tryRedoOperationsThenSelect = function (entity, selection, opers) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var result, context, opers_1, opers_1_1, oper, e_1_1, err_2, missedRows;
|
||||
var e_1, _a;
|
||||
var result, context, opers_1, opers_1_1, oper, e_2_1, err_3, missedRows;
|
||||
var e_2, _a;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
|
|
@ -193,14 +251,14 @@ var Cache = /** @class */ (function (_super) {
|
|||
return [3 /*break*/, 3];
|
||||
case 6: return [3 /*break*/, 9];
|
||||
case 7:
|
||||
e_1_1 = _b.sent();
|
||||
e_1 = { error: e_1_1 };
|
||||
e_2_1 = _b.sent();
|
||||
e_2 = { error: e_2_1 };
|
||||
return [3 /*break*/, 9];
|
||||
case 8:
|
||||
try {
|
||||
if (opers_1_1 && !opers_1_1.done && (_a = opers_1.return)) _a.call(opers_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
return [7 /*endfinally*/];
|
||||
case 9:
|
||||
if (!true) return [3 /*break*/, 19];
|
||||
|
|
@ -217,9 +275,9 @@ var Cache = /** @class */ (function (_super) {
|
|||
_b.sent();
|
||||
return [2 /*return*/, result];
|
||||
case 13:
|
||||
err_2 = _b.sent();
|
||||
if (!(err_2 instanceof Exception_1.OakRowUnexistedException)) return [3 /*break*/, 15];
|
||||
missedRows = err_2.getRows();
|
||||
err_3 = _b.sent();
|
||||
if (!(err_3 instanceof Exception_1.OakRowUnexistedException)) return [3 /*break*/, 15];
|
||||
missedRows = err_3.getRows();
|
||||
return [4 /*yield*/, this.getAspectWrapper().exec('fetchRows', missedRows)];
|
||||
case 14:
|
||||
_b.sent();
|
||||
|
|
@ -227,7 +285,7 @@ var Cache = /** @class */ (function (_super) {
|
|||
case 15: return [4 /*yield*/, context.rollback()];
|
||||
case 16:
|
||||
_b.sent();
|
||||
throw err_2;
|
||||
throw err_3;
|
||||
case 17: return [3 /*break*/, 18];
|
||||
case 18: return [3 /*break*/, 9];
|
||||
case 19: return [2 /*return*/];
|
||||
|
|
|
|||
|
|
@ -1,122 +1,112 @@
|
|||
import { EntityDict, Context, DeduceUpdateOperation, StorageSchema, OpRecord, SelectRowShape, DeduceOperation, AspectWrapper } from "oak-domain/lib/types";
|
||||
import { EntityDict, Context, StorageSchema, OpRecord, SelectRowShape, DeduceSorterItem, AspectWrapper } from "oak-domain/lib/types";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { NamedFilterItem, NamedSorterItem } from "../types/NamedCondition";
|
||||
import { Cache } from './cache';
|
||||
import { Pagination } from '../types/Pagination';
|
||||
import { Feature } from '../types/Feature';
|
||||
declare type Operation<ED extends EntityDict & BaseEntityDict, T extends keyof ED, OmitId extends boolean = false> = {
|
||||
oper: OmitId extends true ? Omit<ED[T]['Operation'], 'id'> : ED[T]['Operation'];
|
||||
beforeExecute?: () => Promise<void>;
|
||||
afterExecute?: () => Promise<void>;
|
||||
};
|
||||
declare abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends CommonAspectDict<ED, Cxt>> {
|
||||
protected entity: T;
|
||||
protected schema: StorageSchema<ED>;
|
||||
protected projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>);
|
||||
protected parent?: Node<ED, keyof ED, Cxt, AD>;
|
||||
protected action?: ED[T]['Action'];
|
||||
protected dirty?: string;
|
||||
protected updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data'];
|
||||
protected dirty?: boolean;
|
||||
protected cache: Cache<ED, Cxt, AD>;
|
||||
protected refreshing: boolean;
|
||||
private beforeExecute?;
|
||||
private afterExecute?;
|
||||
abstract onCacheSync(opRecords: OpRecord<ED>[]): Promise<void>;
|
||||
abstract refreshValue(): void;
|
||||
private syncHandler;
|
||||
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']);
|
||||
protected loading: boolean;
|
||||
protected loadingMore: boolean;
|
||||
protected executing: boolean;
|
||||
protected operations: Operation<ED, T>[];
|
||||
protected modiIds: string[];
|
||||
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 setForeignKey(attr: string, entity: keyof ED, id: string | undefined): Promise<void>;
|
||||
private setLocalUpdateData;
|
||||
setUpdateData(attr: string, value: any): Promise<void>;
|
||||
getUpdateData(): import("oak-domain/lib/types").DeduceUpdateOperationData<ED[T]["OpSchema"]>;
|
||||
setMultiUpdateData(updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data']): Promise<void>;
|
||||
setDirty(): Promise<void>;
|
||||
setAction(action: ED[T]['Action']): Promise<void>;
|
||||
protected abstract getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string;
|
||||
/**
|
||||
* 这个函数从某个结点向父亲查询,看所在路径上是否有需要被应用的modi
|
||||
*/
|
||||
getModiIds(child: Node<ED, keyof ED, Cxt, AD>): string[];
|
||||
setDirty(): void;
|
||||
isDirty(): boolean;
|
||||
isLoading(): boolean;
|
||||
isLoadingMore(): boolean;
|
||||
isExecuting(): boolean;
|
||||
setExecuting(executing: boolean): void;
|
||||
getParent(): Node<ED, keyof ED, Cxt, AD> | undefined;
|
||||
getProjection(): Promise<ED[T]["Selection"]["data"]>;
|
||||
setBeforeExecute(_beforeExecute?: (updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data'], action: ED[T]['Action']) => Promise<void>): void;
|
||||
setAfterExecute(_afterExecute?: (updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data'], action: ED[T]['Action']) => Promise<void>): void;
|
||||
getBeforeExecute(): ((updateData: import("oak-domain/lib/types").DeduceUpdateOperationData<ED[T]["OpSchema"]>, action: ED[T]["Action"]) => Promise<void>) | undefined;
|
||||
getAfterExecute(): ((updateData: import("oak-domain/lib/types").DeduceUpdateOperationData<ED[T]["OpSchema"]>, action: ED[T]["Action"]) => Promise<void>) | undefined;
|
||||
destroy(): void;
|
||||
protected judgeRelation(attr: string): string | 0 | 1 | string[] | 2;
|
||||
protected getProjection(): Promise<ED[T]["Selection"]["data"]>;
|
||||
protected judgeRelation(attr: string): string | 0 | 2 | 1 | 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;
|
||||
}
|
||||
declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Node<ED, T, Cxt, AD> {
|
||||
private children;
|
||||
private newBorn;
|
||||
private filters;
|
||||
private sorters;
|
||||
private pagination;
|
||||
private projectionShape;
|
||||
private ids;
|
||||
private syncHandler;
|
||||
protected getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string;
|
||||
onCacheSync(records: OpRecord<ED>[]): Promise<void>;
|
||||
destroy(): void;
|
||||
setForeignKey(attr: string, entity: keyof ED, id: string | undefined): 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);
|
||||
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>, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], pagination?: Pagination);
|
||||
getPagination(): Pagination;
|
||||
setPagination(pagination: Pagination): void;
|
||||
setPagination(pagination: Pagination): Promise<void>;
|
||||
getChild(path: string, newBorn?: true): SingleNode<ED, T, Cxt, AD> | undefined;
|
||||
getChildren(): SingleNode<ED, T, Cxt, AD>[];
|
||||
getNewBorn(): SingleNode<ED, T, Cxt, AD>[];
|
||||
addChild(path: string, node: SingleNode<ED, T, Cxt, AD>): void;
|
||||
removeChild(path: string): void;
|
||||
setValue(value: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']>[] | undefined): Promise<void>;
|
||||
private appendValue;
|
||||
getNamedFilters(): NamedFilterItem<ED, T>[];
|
||||
getNamedFilterByName(name: string): NamedFilterItem<ED, T> | undefined;
|
||||
setNamedFilters(filters: NamedFilterItem<ED, T>[]): void;
|
||||
addNamedFilter(filter: NamedFilterItem<ED, T>): void;
|
||||
removeNamedFilter(filter: NamedFilterItem<ED, T>): void;
|
||||
removeNamedFilterByName(name: string): void;
|
||||
setNamedFilters(filters: NamedFilterItem<ED, T>[], refresh?: boolean): Promise<void>;
|
||||
addNamedFilter(filter: NamedFilterItem<ED, T>, refresh?: boolean): Promise<void>;
|
||||
removeNamedFilter(filter: NamedFilterItem<ED, T>, refresh?: boolean): Promise<void>;
|
||||
removeNamedFilterByName(name: string, refresh?: boolean): Promise<void>;
|
||||
getNamedSorters(): NamedSorterItem<ED, T>[];
|
||||
getNamedSorterByName(name: string): NamedSorterItem<ED, T> | undefined;
|
||||
setNamedSorters(sorters: NamedSorterItem<ED, T>[]): void;
|
||||
addNamedSorter(sorter: NamedSorterItem<ED, T>): void;
|
||||
removeNamedSorter(sorter: NamedSorterItem<ED, T>): void;
|
||||
removeNamedSorterByName(name: string): void;
|
||||
getFreshValue(): Array<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']> | undefined>;
|
||||
getAction(): "update" | ED[T]["Action"];
|
||||
composeOperation(action?: string, execute?: boolean): Promise<DeduceOperation<ED[T]['Schema']> | DeduceOperation<ED[T]['Schema']>[] | undefined>;
|
||||
refresh(): Promise<void>;
|
||||
setNamedSorters(sorters: NamedSorterItem<ED, T>[], refresh?: boolean): Promise<void>;
|
||||
addNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
|
||||
removeNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
|
||||
removeNamedSorterByName(name: string, refresh: boolean): Promise<void>;
|
||||
getFreshValue(): Promise<Array<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>>>;
|
||||
addOperation(oper: Omit<ED[T]['Operation'], 'id'>, beforeExecute?: Operation<ED, T>['beforeExecute'], afterExecute?: Operation<ED, T>['afterExecute']): Promise<void>;
|
||||
composeOperations(): Promise<Operation<ED, T, false>[] | undefined>;
|
||||
getProjection(): Promise<ED[T]['Selection']['data']>;
|
||||
constructSelection(withParent?: true): Promise<{
|
||||
data: ED[T]["Selection"]["data"];
|
||||
filters: ED[T]["Selection"]["filter"][];
|
||||
sorter: DeduceSorterItem<ED[T]["Schema"]>[];
|
||||
}>;
|
||||
refresh(pageNumber?: number, getCount?: true, append?: boolean): Promise<void>;
|
||||
loadMore(): Promise<void>;
|
||||
setCurrentPage<T extends keyof ED>(currentPage: number, append?: boolean): Promise<void>;
|
||||
resetUpdateData(): Promise<void>;
|
||||
pushNewBorn(options: Pick<CreateNodeOptions<ED, T>, 'updateData' | 'beforeExecute' | 'afterExecute'>): Promise<SingleNode<ED, T, Cxt, AD>>;
|
||||
popNewBorn(path: string): void;
|
||||
/**
|
||||
* 判断传入的updateData和当前的某项是否相等
|
||||
* @param from 当前项
|
||||
* @param to 传入项
|
||||
* @returns
|
||||
*/
|
||||
private judgeTheSame;
|
||||
setUniqueChildren(data: Pick<CreateNodeOptions<ED, T>, 'updateData' | 'beforeExecute' | 'afterExecute'>[]): Promise<void>;
|
||||
toggleChild(data: Pick<CreateNodeOptions<ED, T>, 'updateData' | 'beforeExecute' | 'afterExecute'>, checked: boolean): Promise<void>;
|
||||
clean(): void;
|
||||
}
|
||||
declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Node<ED, T, Cxt, AD> {
|
||||
private id?;
|
||||
private value?;
|
||||
private freshValue?;
|
||||
private children;
|
||||
onCacheSync(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']);
|
||||
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>);
|
||||
protected getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string;
|
||||
destroy(): void;
|
||||
getChild(path: string): SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
|
||||
setId(id: string): Promise<void>;
|
||||
getChildren(): {
|
||||
[K: string]: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
|
||||
};
|
||||
addChild(path: string, node: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>): void;
|
||||
removeChild(path: string): void;
|
||||
refreshValue(): void;
|
||||
setValue(value: SelectRowShape<ED[T]['OpSchema'], ED[T]['Selection']['data']> | undefined): Promise<void>;
|
||||
getFreshValue(ignoreRemoved?: boolean): (SelectRowShape<ED[T]["OpSchema"], ED[T]["Selection"]["data"]> & import("oak-domain/lib/types").DeduceUpdateOperationData<ED[T]["OpSchema"]>) | SelectRowShape<ED[T]["Schema"], ED[T]["Selection"]["data"]> | undefined;
|
||||
getAction(): "create" | "update" | ED[T]["Action"];
|
||||
composeOperation(action2?: string, execute?: boolean): Promise<DeduceUpdateOperation<ED[T]["Schema"]> | undefined>;
|
||||
refresh(scene: string): Promise<void>;
|
||||
resetUpdateData(attrs?: string[]): Promise<void>;
|
||||
setForeignKey(attr: string, entity: keyof ED, id: string | undefined): Promise<void>;
|
||||
getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>>;
|
||||
addOperation(oper: Omit<ED[T]['Operation'], 'id'>, beforeExecute?: Operation<ED, T>['beforeExecute'], afterExecute?: Operation<ED, T>['afterExecute']): Promise<void>;
|
||||
composeOperations(): Promise<Operation<ED, T, false>[] | undefined>;
|
||||
getProjection(): Promise<ED[T]["Selection"]["data"]>;
|
||||
refresh(): Promise<void>;
|
||||
clean(): void;
|
||||
getOtmFilter<T2 extends keyof ED>(childNode: ListNode<ED, keyof ED, Cxt, AD>): ED[T2]['Selection']['filter'];
|
||||
}
|
||||
export declare type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
path: string;
|
||||
parent?: string;
|
||||
entity: T;
|
||||
isList?: boolean;
|
||||
isPicker?: boolean;
|
||||
|
|
@ -124,12 +114,9 @@ export declare type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T
|
|||
pagination?: Pagination;
|
||||
filters?: NamedFilterItem<ED, T>[];
|
||||
sorters?: NamedSorterItem<ED, T>[];
|
||||
action?: ED[T]['Action'];
|
||||
beforeExecute?: (operations: ED[T]['Operation'][]) => Promise<void>;
|
||||
afterExecute?: (operations: ED[T]['Operation'][]) => Promise<void>;
|
||||
id?: string;
|
||||
ids?: string[];
|
||||
updateData?: DeduceUpdateOperation<ED[T]['OpSchema']>['data'];
|
||||
beforeExecute?: (updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data'], action: ED[T]['Action']) => Promise<void>;
|
||||
afterExecute?: (updateData: DeduceUpdateOperation<ED[T]['OpSchema']>['data'], action: ED[T]['Action']) => Promise<void>;
|
||||
};
|
||||
export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt extends Context<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Feature<ED, Cxt, AD> {
|
||||
private cache;
|
||||
|
|
@ -139,19 +126,17 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
|
|||
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): Promise<ListNode<ED, T, Cxt, AD> | SingleNode<ED, T, Cxt, AD>>;
|
||||
private findNode;
|
||||
destroyNode(path: string): void;
|
||||
private applyOperation;
|
||||
getFreshValue(path: string): (SelectRowShape<ED[keyof ED]["OpSchema"], ED[keyof ED]["Selection"]["data"]> & import("oak-domain/lib/types").DeduceUpdateOperationData<ED[keyof ED]["OpSchema"]>) | SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]> | (SelectRowShape<ED[keyof ED]["Schema"], ED[keyof ED]["Selection"]["data"]> | undefined)[] | undefined;
|
||||
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"]>[]>;
|
||||
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(parent: string, attr: string, id: string | undefined): Promise<void>;
|
||||
addForeignKeys(parent: string, attr: string, ids: string[]): Promise<void>;
|
||||
setUniqueForeignKeys(parent: string, attr: string, ids: string[]): Promise<void>;
|
||||
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;
|
||||
isLoadingMore(path: string): boolean;
|
||||
isExecuting(path: string): boolean;
|
||||
refresh(path: string): Promise<void>;
|
||||
loadMore(path: string): Promise<void>;
|
||||
getPagination<T extends keyof ED>(path: string): Pagination;
|
||||
setPageSize<T extends keyof ED>(path: string, pageSize: number): void;
|
||||
setId(path: string, id: string): Promise<void>;
|
||||
setPageSize<T extends keyof ED>(path: string, pageSize: number): Promise<void>;
|
||||
setCurrentPage<T extends keyof ED>(path: string, currentPage: number): 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;
|
||||
|
|
@ -165,16 +150,9 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
|
|||
addNamedSorter<T extends keyof ED>(path: string, sorter: NamedSorterItem<ED, T>, refresh?: boolean): Promise<void>;
|
||||
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>;
|
||||
testAction(path: string, action: string, execute?: boolean): Promise<{
|
||||
node: SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>;
|
||||
operation: DeduceOperation<ED[keyof ED]["Schema"]> | DeduceOperation<ED[keyof ED]["Schema"]>[];
|
||||
}>;
|
||||
private beforeExecute;
|
||||
execute(path: string, action: string): Promise<DeduceOperation<ED[keyof ED]["Schema"]> | DeduceOperation<ED[keyof ED]["Schema"]>[]>;
|
||||
pushNode<T extends keyof ED>(path: string, options: Pick<CreateNodeOptions<ED, T>, 'updateData' | 'beforeExecute' | 'afterExecute'>): Promise<SingleNode<ED, keyof ED, Cxt, AD>>;
|
||||
removeNode(parent: string, path: string): Promise<void>;
|
||||
resetUpdateData(path: string): Promise<void>;
|
||||
toggleNode(path: string, nodeData: Record<string, any>, checked: boolean): Promise<void>;
|
||||
tryExecute(path: string): Promise<void>;
|
||||
execute(path: string): Promise<void>;
|
||||
clean(path: string): void;
|
||||
getRoot(): Record<string, SingleNode<ED, keyof ED, Cxt, AD> | ListNode<ED, keyof ED, Cxt, AD>>;
|
||||
}
|
||||
export {};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,9 +29,6 @@ function initialize(storageSchema, createFeatures, frontendContextBuilder, backe
|
|||
// 初始化i8n配置
|
||||
var i18n = (0, i18n_1.getI18next)(i18nOptions);
|
||||
Object.assign(global, {
|
||||
OakPage: function (options) {
|
||||
return (0, page_mp_1.createPage)(options, features, exceptionRouterDict);
|
||||
},
|
||||
OakComponent: function (options) {
|
||||
return (0, page_mp_1.createComponent)(options, features, exceptionRouterDict);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.initialize = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
require("./utils/wx.polyfill");
|
||||
var page_web_1 = require("./page.web");
|
||||
var page_web2_1 = require("./page.web2");
|
||||
var initialize_dev_1 = require("./initialize-dev");
|
||||
var i18n_1 = require("./platforms/web/i18n");
|
||||
function initialize(storageSchema, createFeatures, frontendContextBuilder, backendContextBuilder, aspectDict, exceptionRouters, triggers, checkers, watchers, initialData, actionDict, i18nOptions) {
|
||||
|
|
@ -29,11 +29,8 @@ function initialize(storageSchema, createFeatures, frontendContextBuilder, backe
|
|||
// 初始化i8n配置
|
||||
var i18n = (0, i18n_1.getI18next)(i18nOptions);
|
||||
Object.assign(global, {
|
||||
OakPage: function (options) {
|
||||
return (0, page_web_1.createPage)(options, features, exceptionRouterDict);
|
||||
},
|
||||
OakComponent: function (options) {
|
||||
return (0, page_web_1.createComponent)(options, features, exceptionRouterDict);
|
||||
return (0, page_web2_1.createComponent)(options, features, exceptionRouterDict);
|
||||
},
|
||||
});
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@ function initialize(storageSchema, createFeatures, frontendContextBuilder, excep
|
|||
// 初始化locales
|
||||
var i18n = (0, i18n_1.getI18next)(i18nOptions);
|
||||
Object.assign(global, {
|
||||
OakPage: function (options) {
|
||||
return (0, page_mp_1.createPage)(options, features, exceptionRouterDict);
|
||||
},
|
||||
OakComponent: function (options) {
|
||||
return (0, page_mp_1.createComponent)(options, features, exceptionRouterDict);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.initialize = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
require("./utils/wx.polyfill");
|
||||
var page_web_1 = require("./page.web");
|
||||
var page_web2_1 = require("./page.web2");
|
||||
var initialize_prod_1 = require("./initialize-prod");
|
||||
var i18n_1 = require("./platforms/web/i18n");
|
||||
function initialize(storageSchema, createFeatures, frontendContextBuilder, exceptionRouters, connector, checkers, actionDict, i18nOptions) {
|
||||
|
|
@ -29,11 +29,8 @@ function initialize(storageSchema, createFeatures, frontendContextBuilder, excep
|
|||
// 初始化i8n配置
|
||||
var i18n = (0, i18n_1.getI18next)(i18nOptions);
|
||||
Object.assign(global, {
|
||||
OakPage: function (options) {
|
||||
return (0, page_web_1.createPage)(options, features, exceptionRouterDict);
|
||||
},
|
||||
OakComponent: function (options) {
|
||||
return (0, page_web_1.createComponent)(options, features, exceptionRouterDict);
|
||||
return (0, page_web2_1.createComponent)(options, features, exceptionRouterDict);
|
||||
},
|
||||
});
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature } from './types/Feature';
|
||||
import { OakCommonComponentMethods, OakComponentData, OakComponentProperties, OakHiddenComponentMethods, OakListComponentMethods, OakComponentOnlyMethods, OakPageMethods, OakPageOption } from './types/Page';
|
||||
export declare type ComponentProps<TProperty extends WechatMiniprogram.Component.PropertyOption> = WechatMiniprogram.Component.PropertyOptionToData<OakComponentProperties & TProperty>;
|
||||
export declare type ComponentData<ED extends EntityDict & BaseEntityDict, T extends keyof ED, FormedData extends WechatMiniprogram.Component.DataOption, TData extends WechatMiniprogram.Component.DataOption> = TData & FormedData & OakComponentData<ED, T>;
|
||||
export declare type ComponentThisType<ED extends EntityDict & BaseEntityDict, T extends keyof ED, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption> = ThisType<{
|
||||
state: ComponentData<ED, T, FormedData, TData>;
|
||||
props: ComponentProps<TProperty>;
|
||||
setState: (data: any, callback?: () => void) => Promise<void>;
|
||||
triggerEvent: <DetailType = any>(name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption) => void;
|
||||
} & TMethod & OakCommonComponentMethods<ED, T> & OakHiddenComponentMethods & (IsList extends true ? OakListComponentMethods<ED, T> : {})>;
|
||||
export declare function makeHiddenComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption>(): OakHiddenComponentMethods & ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod>;
|
||||
export declare function makeCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, Proj extends ED[T]['Selection']['data'], IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>, formData: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>['formData']): Omit<OakCommonComponentMethods<ED, T>, 'navigateTo' | 'navigateBack' | 'resolveInput' | 'redirectTo' | 't'> & ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod>;
|
||||
export declare function makeComponentOnlyMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, Proj extends ED[T]['Selection']['data'], IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(formData: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>['formData'], entity: T | undefined, actions: ED[T]['Action'][] | undefined): OakComponentOnlyMethods & ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod>;
|
||||
export declare function makeListComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD): OakListComponentMethods<ED, T> & ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod>;
|
||||
export declare function makePageMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, Proj extends ED[T]['Selection']['data'], IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>): OakPageMethods & ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod>;
|
||||
1008
lib/page.common.js
1008
lib/page.common.js
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,12 @@
|
|||
import { Context, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { OakComponentOption, ComponentFullThisType } from './types/Page2';
|
||||
export declare function subscribe<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>): void;
|
||||
export declare function unsubscribe<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>>(this: ComponentFullThisType<ED, T, Cxt>): void;
|
||||
export declare function onPathSet<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, {}, {}, {}>): Promise<void>;
|
||||
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>, legalExceptions?: Array<string>, path?: string): Promise<void>;
|
||||
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>;
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.setUpdateData = exports.callPicker = exports.execute = exports.loadMore = exports.refresh = exports.reRender = exports.onPathSet = exports.unsubscribe = exports.subscribe = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = require("oak-domain/lib/utils/assert");
|
||||
var types_1 = require("oak-domain/lib/types");
|
||||
var Feature_1 = require("./types/Feature");
|
||||
function subscribe() {
|
||||
var _this = this;
|
||||
if (!this.subscribed) {
|
||||
this.subscribed = (0, Feature_1.subscribe)(function () { return _this.reRender(); });
|
||||
}
|
||||
}
|
||||
exports.subscribe = subscribe;
|
||||
function unsubscribe() {
|
||||
if (this.subscribed) {
|
||||
this.subscribed();
|
||||
this.subscribed = undefined;
|
||||
}
|
||||
}
|
||||
exports.unsubscribe = unsubscribe;
|
||||
function onPathSet(option) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var _a, props, state, oakEntity, oakPath, oakProjection, oakIsPicker, oakFilters, oakSorters, oakId, entity, path, projection, isList, filters, sorters, pagination, features, filters2, oakFilters2, _loop_1, filters_1, filters_1_1, ele, proj, sorters2, oakSorters2, _loop_2, sorters_1, sorters_1_1, ele, oakPath2;
|
||||
var e_1, _b, e_2, _c;
|
||||
return tslib_1.__generator(this, function (_d) {
|
||||
switch (_d.label) {
|
||||
case 0:
|
||||
_a = this, props = _a.props, state = _a.state;
|
||||
oakEntity = props.oakEntity, oakPath = props.oakPath, oakProjection = props.oakProjection, oakIsPicker = props.oakIsPicker, oakFilters = props.oakFilters, oakSorters = props.oakSorters, oakId = props.oakId;
|
||||
entity = option.entity, path = option.path, projection = option.projection, isList = option.isList, filters = option.filters, sorters = option.sorters, pagination = option.pagination;
|
||||
features = this.features;
|
||||
filters2 = [];
|
||||
if (oakFilters) {
|
||||
oakFilters2 = typeof oakFilters === 'string' ? JSON.parse(oakFilters) : oakFilters;
|
||||
filters2.push.apply(filters2, tslib_1.__spreadArray([], tslib_1.__read(oakFilters2), false));
|
||||
}
|
||||
else if (filters) {
|
||||
_loop_1 = function (ele) {
|
||||
var _e;
|
||||
var filter = ele.filter, name_1 = ele["#name"];
|
||||
filters2.push((_e = {
|
||||
filter: typeof filter === 'function'
|
||||
? function () {
|
||||
return filter({
|
||||
features: features,
|
||||
props: props,
|
||||
state: state
|
||||
});
|
||||
}
|
||||
: filter
|
||||
},
|
||||
_e['#name'] = name_1,
|
||||
_e));
|
||||
};
|
||||
try {
|
||||
for (filters_1 = tslib_1.__values(filters), filters_1_1 = filters_1.next(); !filters_1_1.done; filters_1_1 = filters_1.next()) {
|
||||
ele = filters_1_1.value;
|
||||
_loop_1(ele);
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (filters_1_1 && !filters_1_1.done && (_b = filters_1.return)) _b.call(filters_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
}
|
||||
proj = oakProjection && (typeof oakProjection === 'string' ? JSON.parse(oakProjection) : oakProjection);
|
||||
if (!proj && projection) {
|
||||
proj = typeof projection === 'function'
|
||||
? function () {
|
||||
return projection({
|
||||
features: features,
|
||||
props: props,
|
||||
state: state,
|
||||
});
|
||||
}
|
||||
: projection;
|
||||
}
|
||||
sorters2 = [];
|
||||
if (oakSorters) {
|
||||
oakSorters2 = typeof oakSorters === 'string' ? JSON.parse(oakSorters) : oakSorters;
|
||||
sorters2.push.apply(sorters2, tslib_1.__spreadArray([], tslib_1.__read(oakSorters2), false));
|
||||
}
|
||||
else if (sorters) {
|
||||
_loop_2 = function (ele) {
|
||||
var _f;
|
||||
var sorter = ele.sorter, name_2 = ele["#name"];
|
||||
sorters.push((_f = {
|
||||
sorter: typeof sorter === 'function'
|
||||
? function () {
|
||||
return sorter({
|
||||
features: features,
|
||||
props: props,
|
||||
state: state,
|
||||
});
|
||||
}
|
||||
: sorter
|
||||
},
|
||||
_f['#name'] = name_2,
|
||||
_f));
|
||||
};
|
||||
try {
|
||||
for (sorters_1 = tslib_1.__values(sorters), sorters_1_1 = sorters_1.next(); !sorters_1_1.done; sorters_1_1 = sorters_1.next()) {
|
||||
ele = sorters_1_1.value;
|
||||
_loop_2(ele);
|
||||
}
|
||||
}
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (sorters_1_1 && !sorters_1_1.done && (_c = sorters_1.return)) _c.call(sorters_1);
|
||||
}
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
}
|
||||
}
|
||||
oakPath2 = oakPath || path;
|
||||
(0, assert_1.assert)(oakPath2, '没有正确的path信息,请检查是否配置正确');
|
||||
return [4 /*yield*/, features.runningTree.createNode({
|
||||
path: oakPath2,
|
||||
entity: (oakEntity || entity),
|
||||
isList: isList,
|
||||
isPicker: oakIsPicker,
|
||||
projection: proj,
|
||||
pagination: pagination,
|
||||
filters: filters2,
|
||||
sorters: sorters2,
|
||||
id: oakId,
|
||||
})];
|
||||
case 1:
|
||||
_d.sent();
|
||||
Object.assign(this.state, {
|
||||
oakEntity: (oakEntity || entity),
|
||||
oakFullpath: oakPath2,
|
||||
oakIsReady: true,
|
||||
});
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.onPathSet = onPathSet;
|
||||
function reRender(option, extra) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var features, formData, rows, oakDirty, oakLoading, oakLoadingMore, oakExecuting, data, _a, k, data, _b;
|
||||
var _c;
|
||||
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*/, 5];
|
||||
return [4 /*yield*/, this.features.runningTree.getFreshValue(this.state.oakFullpath)];
|
||||
case 1:
|
||||
rows = _d.sent();
|
||||
oakDirty = this.features.runningTree.isDirty(this.state.oakFullpath);
|
||||
oakLoading = this.features.runningTree.isLoading(this.state.oakFullpath);
|
||||
oakLoadingMore = this.features.runningTree.isLoadingMore(this.state.oakFullpath);
|
||||
oakExecuting = this.features.runningTree.isExecuting(this.state.oakFullpath);
|
||||
if (!formData) return [3 /*break*/, 3];
|
||||
return [4 /*yield*/, formData.call(this, {
|
||||
data: rows,
|
||||
features: features,
|
||||
props: this.props,
|
||||
})];
|
||||
case 2:
|
||||
_a = _d.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
_a = {};
|
||||
_d.label = 4;
|
||||
case 4:
|
||||
data = _a;
|
||||
for (k in data) {
|
||||
if (data[k] === undefined) {
|
||||
Object.assign(data, (_c = {},
|
||||
_c[k] = null,
|
||||
_c));
|
||||
}
|
||||
}
|
||||
Object.assign(data, { oakDirty: oakDirty, oakLoading: oakLoading, oakLoadingMore: oakLoadingMore, oakExecuting: oakExecuting });
|
||||
if (extra) {
|
||||
Object.assign(data, extra);
|
||||
}
|
||||
this.setState(data);
|
||||
return [3 /*break*/, 9];
|
||||
case 5:
|
||||
if (!formData) return [3 /*break*/, 7];
|
||||
return [4 /*yield*/, formData.call(this, {
|
||||
features: features,
|
||||
props: this.props,
|
||||
})];
|
||||
case 6:
|
||||
_b = _d.sent();
|
||||
return [3 /*break*/, 8];
|
||||
case 7:
|
||||
_b = {};
|
||||
_d.label = 8;
|
||||
case 8:
|
||||
data = _b;
|
||||
if (extra) {
|
||||
Object.assign(data, extra);
|
||||
}
|
||||
this.setState(data);
|
||||
_d.label = 9;
|
||||
case 9: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.reRender = reRender;
|
||||
function refresh() {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var err_1;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(this.state.oakEntity && this.state.oakFullpath)) return [3 /*break*/, 4];
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, this.features.runningTree.refresh(this.state.oakFullpath)];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
err_1 = _a.sent();
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: err_1.message,
|
||||
});
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.refresh = refresh;
|
||||
function loadMore() {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var err_2;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!(this.state.oakEntity && this.state.oakFullpath)) return [3 /*break*/, 4];
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, this.features.runningTree.loadMore(this.state.oakFullpath)];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
err_2 = _a.sent();
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: err_2.message,
|
||||
});
|
||||
return [3 /*break*/, 4];
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.loadMore = loadMore;
|
||||
function execute(legalExceptions, path) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var fullpath, result, err_3, attr, name_3;
|
||||
var _a;
|
||||
return tslib_1.__generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
if (this.state.oakExecuting) {
|
||||
return [2 /*return*/];
|
||||
}
|
||||
this.setState({
|
||||
oakFocused: {},
|
||||
});
|
||||
_b.label = 1;
|
||||
case 1:
|
||||
_b.trys.push([1, 3, , 4]);
|
||||
fullpath = path
|
||||
? "".concat(this.state.oakFullpath, ".").concat(path)
|
||||
: this.state.oakFullpath;
|
||||
return [4 /*yield*/, this.features.runningTree.execute(fullpath)];
|
||||
case 2:
|
||||
result = _b.sent();
|
||||
this.setMessage({
|
||||
type: 'success',
|
||||
content: '操作成功',
|
||||
});
|
||||
return [2 /*return*/, result];
|
||||
case 3:
|
||||
err_3 = _b.sent();
|
||||
if (err_3 instanceof types_1.OakException) {
|
||||
if (err_3 instanceof types_1.OakInputIllegalException) {
|
||||
attr = err_3.getAttributes()[0];
|
||||
this.setState({
|
||||
oakFocused: (_a = {},
|
||||
_a[attr] = true,
|
||||
_a),
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'warning',
|
||||
content: err_3.message,
|
||||
});
|
||||
}
|
||||
else {
|
||||
name_3 = err_3.constructor.name;
|
||||
if (legalExceptions && legalExceptions.includes(name_3)) {
|
||||
// 如果调用时就知道有异常,直接抛出
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
throw err_3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.setMessage({
|
||||
type: 'warning',
|
||||
content: err_3.message,
|
||||
});
|
||||
}
|
||||
throw err_3;
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.execute = execute;
|
||||
function callPicker(attr, params) {
|
||||
if (params === void 0) { params = {}; }
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
var relation = this.features.cache.judgeRelation(this.state.oakEntity, attr);
|
||||
var subEntity;
|
||||
if (relation === 2) {
|
||||
subEntity = attr;
|
||||
}
|
||||
else {
|
||||
(0, assert_1.assert)(typeof relation === 'string');
|
||||
subEntity = relation;
|
||||
}
|
||||
var url = "/pickers/".concat(subEntity, "?oakIsPicker=true&oakParentEntity=").concat(this.state.oakEntity, "&oakParent=").concat(this.state.oakFullpath, "&oakPath=").concat(attr);
|
||||
for (var k in params) {
|
||||
url += "&".concat(k, "=").concat(JSON.stringify(params[k]));
|
||||
}
|
||||
this.navigateTo({
|
||||
url: url,
|
||||
});
|
||||
}
|
||||
exports.callPicker = callPicker;
|
||||
function setUpdateData(attr, data) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var id;
|
||||
var _a, _b;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
(0, assert_1.assert)(attr.indexOf('.') === -1, 'setUpdateData只能设置当前对象属性,子层对象请写完整的addOperation');
|
||||
if (!this.props.oakId) return [3 /*break*/, 1];
|
||||
return [2 /*return*/, this.addOperation({
|
||||
action: 'update',
|
||||
data: (_a = {},
|
||||
_a[attr] = data,
|
||||
_a)
|
||||
})];
|
||||
case 1: return [4 /*yield*/, generateNewId()];
|
||||
case 2:
|
||||
id = _c.sent();
|
||||
return [4 /*yield*/, this.addOperation({
|
||||
action: 'create',
|
||||
data: (_b = {
|
||||
id: id
|
||||
},
|
||||
_b[attr] = data,
|
||||
_b)
|
||||
})];
|
||||
case 3:
|
||||
_c.sent();
|
||||
this.setProps({ oakId: id });
|
||||
_c.label = 4;
|
||||
case 4: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.setUpdateData = setUpdateData;
|
||||
|
|
@ -5,6 +5,6 @@ import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
|
|||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature } from './types/Feature';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page2';
|
||||
export declare function createPage<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, 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: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>): string;
|
||||
export declare function createComponent<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, 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, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>): string;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ var tslib_1 = require("tslib");
|
|||
var lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
var url_1 = tslib_1.__importDefault(require("url"));
|
||||
var assert_1 = require("oak-domain/lib/utils/assert");
|
||||
var page_common_1 = require("./page.common");
|
||||
var page_common2_1 = require("./page.common2");
|
||||
var i18n_1 = require("./platforms/wechatMp/i18n");
|
||||
function makeCommonComponentMethods(features, exceptionRouterDict, formData) {
|
||||
return tslib_1.__assign({ t: function (key, params) {
|
||||
|
|
@ -154,10 +154,10 @@ function makeCommonComponentMethods(features, exceptionRouterDict, formData) {
|
|||
},
|
||||
}));
|
||||
});
|
||||
} }, (0, page_common_1.makeCommonComponentMethods)(features, exceptionRouterDict, formData));
|
||||
} }, (0, page_common2_1.makeCommonComponentMethods)(features, exceptionRouterDict, formData));
|
||||
}
|
||||
function makePageMethods(features, options) {
|
||||
var _a = (0, page_common_1.makePageMethods)(features, options), onPullDownRefresh = _a.onPullDownRefresh, onLoad = _a.onLoad, rest = tslib_1.__rest(_a, ["onPullDownRefresh", "onLoad"]);
|
||||
var _a = (0, page_common2_1.makePageMethods)(features, options), onPullDownRefresh = _a.onPullDownRefresh, onLoad = _a.onLoad, rest = tslib_1.__rest(_a, ["onPullDownRefresh", "onLoad"]);
|
||||
return tslib_1.__assign({ onPullDownRefresh: function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
|
|
@ -207,10 +207,10 @@ function makePageMethods(features, options) {
|
|||
}
|
||||
function createPage(options, features, exceptionRouterDict) {
|
||||
var formData = options.formData, isList = options.isList, entity = options.entity, actions = options.actions;
|
||||
var hiddenMethods = (0, page_common_1.makeHiddenComponentMethods)();
|
||||
var hiddenMethods = (0, page_common2_1.makeHiddenComponentMethods)();
|
||||
var commonMethods = makeCommonComponentMethods(features, exceptionRouterDict, formData);
|
||||
var listMethods = (0, page_common_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
var listMethods = (0, page_common2_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common2_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
var _a = makePageMethods(features, options), onLoad = _a.onLoad, onPullDownRefresh = _a.onPullDownRefresh, onReachBottom = _a.onReachBottom, restPageMethods = tslib_1.__rest(_a, ["onLoad", "onPullDownRefresh", "onReachBottom"]);
|
||||
var methods = options.methods, lifetimes = options.lifetimes, pageLifetimes = options.pageLifetimes;
|
||||
return Component({
|
||||
|
|
@ -350,10 +350,10 @@ function createPage(options, features, exceptionRouterDict) {
|
|||
exports.createPage = createPage;
|
||||
function createComponent(options, features, exceptionRouterDict) {
|
||||
var formData = options.formData, isList = options.isList, entity = options.entity, methods = options.methods, lifetimes = options.lifetimes, pageLifetimes = options.pageLifetimes, data = options.data, properties = options.properties, actions = options.actions, observers = options.observers, restOptions = tslib_1.__rest(options, ["formData", "isList", "entity", "methods", "lifetimes", "pageLifetimes", "data", "properties", "actions", "observers"]);
|
||||
var hiddenMethods = (0, page_common_1.makeHiddenComponentMethods)();
|
||||
var hiddenMethods = (0, page_common2_1.makeHiddenComponentMethods)();
|
||||
var commonMethods = makeCommonComponentMethods(features, exceptionRouterDict, formData);
|
||||
var listMethods = (0, page_common_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
var listMethods = (0, page_common2_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common2_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
return Component(tslib_1.__assign({ data: Object.assign({}, data, {
|
||||
oakEntity: '',
|
||||
oakFullpath: '',
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
import React from 'react';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature } from './types/Feature';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page';
|
||||
export declare function createPage<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, 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: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>): React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
|
||||
export declare function createComponent<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, 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, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>): React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
|
||||
430
lib/page.web.js
430
lib/page.web.js
|
|
@ -1,430 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createComponent = exports.createPage = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
||||
var react_1 = tslib_1.__importDefault(require("react"));
|
||||
var web_1 = require("./platforms/web");
|
||||
var lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
var page_common_1 = require("./page.common");
|
||||
function makeCommonComponentMethods(features, exceptionRouterDict, formData) {
|
||||
return tslib_1.__assign({ t: function (key, params) {
|
||||
// common: {
|
||||
// GREETING: 'Hello {{name}}, nice to see you.',
|
||||
// },
|
||||
// t('common:GREETING', {name: "John Doe" })
|
||||
return this.props.t(key, params);
|
||||
}, resolveInput: function (input, keys) {
|
||||
var currentTarget = input.currentTarget, target = input.target;
|
||||
var value = Object.assign({}, currentTarget, target).value;
|
||||
var dataset = currentTarget.dataset;
|
||||
var result = {
|
||||
dataset: dataset,
|
||||
value: value,
|
||||
};
|
||||
if (keys) {
|
||||
keys.forEach(function (k) {
|
||||
var _a;
|
||||
return Object.assign(result, (_a = {},
|
||||
_a[k] = target[k],
|
||||
_a));
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}, navigateBack: function (option) {
|
||||
var _this = this;
|
||||
var delta = (option || {}).delta;
|
||||
return new Promise(function (resolve, reject) {
|
||||
try {
|
||||
_this.props.navigate(delta || -1);
|
||||
resolve(undefined);
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}, navigateTo: function (options, state, disableNamespace) {
|
||||
var url = options.url, events = options.events, fail = options.fail, complete = options.complete, success = options.success, rest = tslib_1.__rest(options, ["url", "events", "fail", "complete", "success"]);
|
||||
var url2 = url.includes('?')
|
||||
? url.concat(this.state.oakFullpath
|
||||
? "&oakFrom=".concat(this.state.oakFullpath)
|
||||
: '')
|
||||
: url.concat(this.state.oakFullpath ? "?oakFrom=".concat(this.state.oakFullpath) : '');
|
||||
for (var param in rest) {
|
||||
var param2 = param;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += "".concat(url2.includes('?') ? '&' : '?').concat(param, "=").concat(typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2]));
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: false, state: state });
|
||||
}, redirectTo: function (options, state, disableNamespace) {
|
||||
var url = options.url, events = options.events, fail = options.fail, complete = options.complete, success = options.success, rest = tslib_1.__rest(options, ["url", "events", "fail", "complete", "success"]);
|
||||
var url2 = url.includes('?')
|
||||
? url.concat(this.state.oakFullpath
|
||||
? "&oakFrom=".concat(this.state.oakFullpath)
|
||||
: '')
|
||||
: url.concat(this.state.oakFullpath
|
||||
? "?oakFrom=".concat(this.state.oakFullpath)
|
||||
: '');
|
||||
for (var param in rest) {
|
||||
var param2 = param;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += "".concat(url2.includes('?') ? '&' : '?').concat(param, "=").concat(typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2]));
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: true, state: state });
|
||||
} }, (0, page_common_1.makeCommonComponentMethods)(features, exceptionRouterDict, formData));
|
||||
}
|
||||
function makePageMethods(features, options) {
|
||||
var _a = (0, page_common_1.makePageMethods)(features, options), onPullDownRefresh = _a.onPullDownRefresh, rest = tslib_1.__rest(_a, ["onPullDownRefresh"]);
|
||||
return tslib_1.__assign({ onPullDownRefresh: function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, onPullDownRefresh.call(this)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
} }, rest);
|
||||
}
|
||||
function translateObservers(observers) {
|
||||
return {
|
||||
fn: function (prevProps, prevState) {
|
||||
var e_1, _a, e_2, _b;
|
||||
var _c = this, state = _c.state, props = _c.props;
|
||||
for (var obs in observers) {
|
||||
var keys = obs.split(',').map(function (ele) { return ele.trim(); });
|
||||
var changed = false;
|
||||
try {
|
||||
for (var keys_1 = (e_1 = void 0, tslib_1.__values(keys)), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
|
||||
var k = keys_1_1.value;
|
||||
if (k.includes('*')) {
|
||||
throw new Error('web模式下带*的observer通配符暂不支持');
|
||||
}
|
||||
if ((0, lodash_1.get)(props, k) !== (0, lodash_1.get)(prevProps, k) ||
|
||||
(0, lodash_1.get)(state, k) !== (0, lodash_1.get)(prevState, k)) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
var args = [];
|
||||
if (changed) {
|
||||
try {
|
||||
for (var keys_2 = (e_2 = void 0, tslib_1.__values(keys)), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
|
||||
var k = keys_2_1.value;
|
||||
args.push((0, lodash_1.get)(props, k) === undefined
|
||||
? (0, lodash_1.get)(state, k)
|
||||
: (0, lodash_1.get)(props, k));
|
||||
}
|
||||
}
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (keys_2_1 && !keys_2_1.done && (_b = keys_2.return)) _b.call(keys_2);
|
||||
}
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
}
|
||||
observers[obs].apply(this, args);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
function makeMiniprogramCompatibleFunctions() {
|
||||
return {
|
||||
triggerEvent: function (name, detail, option) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
animate: function (selector, frames, duration, timeline) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
clearAnimation: function (selector, option, callback) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
};
|
||||
}
|
||||
var DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
function createPage(options, features, exceptionRouterDict) {
|
||||
var _a = options, formData = _a.formData, isList = _a.isList, render = _a.render, actions = _a.actions, entity = _a.entity;
|
||||
var hiddenMethods = (0, page_common_1.makeHiddenComponentMethods)();
|
||||
var commonMethods = makeCommonComponentMethods(features, exceptionRouterDict, formData);
|
||||
var listMethods = (0, page_common_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
var _b = makePageMethods(features, options), onLoad = _b.onLoad, onPullDownRefresh = _b.onPullDownRefresh, onReachBottom = _b.onReachBottom, restPageMethods = tslib_1.__rest(_b, ["onLoad", "onPullDownRefresh", "onReachBottom"]);
|
||||
var methods = options.methods, lifetimes = options.lifetimes, pageLifetimes = options.pageLifetimes, data = options.data, observers = options.observers;
|
||||
var fn = translateObservers(observers).fn;
|
||||
var OakPageWrapper = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(OakPageWrapper, _super);
|
||||
function OakPageWrapper(props) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
var _this = _super.call(this, props) || this;
|
||||
_this.features = features;
|
||||
_this.isReachBottom = false;
|
||||
_this.componentDidUpdate = fn;
|
||||
_this.scrollEvent = function () {
|
||||
_this.checkReachBottom();
|
||||
};
|
||||
_this.state = (data || {});
|
||||
for (var m in commonMethods) {
|
||||
Object.assign(_this, (_a = {},
|
||||
_a[m] = commonMethods[m].bind(_this),
|
||||
_a));
|
||||
}
|
||||
for (var m in listMethods) {
|
||||
Object.assign(_this, (_b = {},
|
||||
_b[m] = listMethods[m].bind(_this),
|
||||
_b));
|
||||
}
|
||||
for (var m in hiddenMethods) {
|
||||
Object.assign(_this, (_c = {},
|
||||
_c[m] = hiddenMethods[m].bind(_this),
|
||||
_c));
|
||||
}
|
||||
for (var m in onlyMethods) {
|
||||
Object.assign(_this, (_d = {},
|
||||
_d[m] = onlyMethods[m].bind(_this),
|
||||
_d));
|
||||
}
|
||||
for (var m in restPageMethods) {
|
||||
Object.assign(_this, (_e = {},
|
||||
_e[m] = restPageMethods[m].bind(_this),
|
||||
_e));
|
||||
}
|
||||
if (methods) {
|
||||
var onPullDownRefresh_1 = methods.onPullDownRefresh, onReachBottom_1 = methods.onReachBottom, restMethods = tslib_1.__rest(methods, ["onPullDownRefresh", "onReachBottom"]);
|
||||
for (var m in restMethods) {
|
||||
Object.assign(_this, (_f = {},
|
||||
_f[m] = restMethods[m].bind(_this),
|
||||
_f));
|
||||
}
|
||||
}
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.created) && lifetimes.created.call(_this);
|
||||
return _this;
|
||||
}
|
||||
OakPageWrapper.prototype.registerPageScroll = function () {
|
||||
var _a = this.props.useBodyScroll, useBodyScroll = _a === void 0 ? false : _a;
|
||||
if (useBodyScroll) {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
this.lv && this.lv.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
};
|
||||
OakPageWrapper.prototype.unregisterPageScroll = function () {
|
||||
var _a = this.props.useBodyScroll, useBodyScroll = _a === void 0 ? false : _a;
|
||||
if (useBodyScroll) {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
this.lv && this.lv.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
};
|
||||
OakPageWrapper.prototype.checkReachBottom = function () {
|
||||
var isCurrentReachBottom = document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
if (!this.isReachBottom && isCurrentReachBottom) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
if (methods === null || methods === void 0 ? void 0 : methods.onReachBottom) {
|
||||
methods.onReachBottom.call(this);
|
||||
return;
|
||||
}
|
||||
if (this.props.width === 'xs') {
|
||||
onReachBottom.call(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.isReachBottom = isCurrentReachBottom;
|
||||
};
|
||||
OakPageWrapper.prototype.componentDidMount = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
this.registerPageScroll();
|
||||
return [4 /*yield*/, onLoad.call(this, this.props)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
typeof formData === 'function' && hiddenMethods.subscribe.call(this);
|
||||
typeof formData === 'function' && commonMethods.reRender.call(this);
|
||||
(methods === null || methods === void 0 ? void 0 : methods.onReady) && methods.onReady.call(this);
|
||||
(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);
|
||||
(pageLifetimes === null || pageLifetimes === void 0 ? void 0 : pageLifetimes.show) && pageLifetimes.show.call(this);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakPageWrapper.prototype.componentWillUnmount = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
this.unregisterPageScroll();
|
||||
this.state.oakFullpath && features.runningTree.destroyNode(this.state.oakFullpath);
|
||||
typeof formData === 'function' && hiddenMethods.unsubscribe.call(this);
|
||||
(methods === null || methods === void 0 ? void 0 : methods.onUnload) && methods.onUnload.call(this);
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.detached) && lifetimes.detached.call(this);
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
};
|
||||
OakPageWrapper.prototype.render = function () {
|
||||
var _this = this;
|
||||
var Render = render.call(this);
|
||||
var oakLoading = this.state.oakLoading;
|
||||
var _a = this.props, enablePullDownRefresh = _a.enablePullDownRefresh, _b = _a.useBodyScroll, useBodyScroll = _b === void 0 ? false : _b;
|
||||
if (enablePullDownRefresh && this.props.width === 'xs') {
|
||||
var child = react_1.default.cloneElement((0, jsx_runtime_1.jsx)(web_1.PullToRefresh, { onRefresh: function () {
|
||||
if (methods === null || methods === void 0 ? void 0 : methods.onPullDownRefresh) {
|
||||
methods.onPullDownRefresh.call(_this);
|
||||
}
|
||||
else {
|
||||
onPullDownRefresh.call(_this);
|
||||
}
|
||||
}, refreshing: oakLoading, distanceToRefresh: DEFAULT_REACH_BOTTOM_DISTANCE, indicator: {
|
||||
activate: commonMethods.t.call(this, 'common:ptrActivate'),
|
||||
deactivate: commonMethods.t.call(this, 'common:ptrDeactivate'),
|
||||
release: commonMethods.t.call(this, 'common:ptrRelease'),
|
||||
finish: commonMethods.t.call(this, 'common:ptrFinish'),
|
||||
} }), {
|
||||
getScrollContainer: function () { return useBodyScroll ? document.body : _this.lv; },
|
||||
}, Render);
|
||||
return useBodyScroll ? (child) : ((0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ ref: function (el) { return (_this.lv = el); }, style: { height: '100%', overflow: 'auto' } }, { children: child })));
|
||||
}
|
||||
return Render;
|
||||
};
|
||||
return OakPageWrapper;
|
||||
}(react_1.default.PureComponent));
|
||||
// 可能有问题,by Xc
|
||||
Object.assign(OakPageWrapper, makeMiniprogramCompatibleFunctions());
|
||||
return (0, web_1.withRouter)(OakPageWrapper, false, options.path);
|
||||
}
|
||||
exports.createPage = createPage;
|
||||
function createComponent(options, features, exceptionRouterDict) {
|
||||
var _a = options, formData = _a.formData, isList = _a.isList, entity = _a.entity, methods = _a.methods, lifetimes = _a.lifetimes, pageLifetimes = _a.pageLifetimes, data = _a.data, properties = _a.properties, observers = _a.observers, actions = _a.actions, render = _a.render;
|
||||
var hiddenMethods = (0, page_common_1.makeHiddenComponentMethods)();
|
||||
var commonMethods = makeCommonComponentMethods(features, exceptionRouterDict, formData);
|
||||
var listMethods = (0, page_common_1.makeListComponentMethods)(features);
|
||||
var onlyMethods = (0, page_common_1.makeComponentOnlyMethods)(formData, entity, actions);
|
||||
var fn = translateObservers(observers).fn;
|
||||
var OakComponentWrapper = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(OakComponentWrapper, _super);
|
||||
function OakComponentWrapper(props) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
var _this = _super.call(this, props) || this;
|
||||
_this.features = features;
|
||||
_this.isReachBottom = false;
|
||||
_this.state = (data || {});
|
||||
for (var m in commonMethods) {
|
||||
Object.assign(_this, (_a = {},
|
||||
_a[m] = commonMethods[m].bind(_this),
|
||||
_a));
|
||||
}
|
||||
for (var m in listMethods) {
|
||||
Object.assign(_this, (_b = {},
|
||||
_b[m] = listMethods[m].bind(_this),
|
||||
_b));
|
||||
}
|
||||
for (var m in hiddenMethods) {
|
||||
Object.assign(_this, (_c = {},
|
||||
_c[m] = hiddenMethods[m].bind(_this),
|
||||
_c));
|
||||
}
|
||||
for (var m in onlyMethods) {
|
||||
Object.assign(_this, (_d = {},
|
||||
_d[m] = onlyMethods[m].bind(_this),
|
||||
_d));
|
||||
}
|
||||
if (methods) {
|
||||
for (var m in methods) {
|
||||
Object.assign(_this, (_e = {},
|
||||
_e[m] = methods[m].bind(_this),
|
||||
_e));
|
||||
}
|
||||
}
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.created) && lifetimes.created.call(_this);
|
||||
return _this;
|
||||
}
|
||||
OakComponentWrapper.prototype.componentDidMount = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
typeof formData === 'function' && hiddenMethods.subscribe.call(this);
|
||||
this.setOakActions();
|
||||
this.registerReRender();
|
||||
(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);
|
||||
(pageLifetimes === null || pageLifetimes === void 0 ? void 0 : pageLifetimes.show) && pageLifetimes.show.call(this);
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentWrapper.prototype.componentWillUnmount = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
typeof formData === 'function' && hiddenMethods.unsubscribe.call(this);
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.detached) && lifetimes.detached.call(this);
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentWrapper.prototype.componentDidUpdate = function (prevProps, prevState) {
|
||||
if (this.props.oakPath &&
|
||||
prevProps.oakPath !== this.props.oakPath) {
|
||||
this.onPropsChanged({
|
||||
path: this.props.oakPath,
|
||||
});
|
||||
}
|
||||
if (this.props.oakParent &&
|
||||
prevProps.oakParent !== this.props.oakParent) {
|
||||
this.onPropsChanged({
|
||||
parent: this.props.oakParent,
|
||||
});
|
||||
}
|
||||
fn === null || fn === void 0 ? void 0 : fn.call(this, prevProps, prevState);
|
||||
};
|
||||
OakComponentWrapper.prototype.render = function () {
|
||||
var Render = render.call(this);
|
||||
return Render;
|
||||
};
|
||||
OakComponentWrapper.prototype.triggerEvent = function (name, detail, options) {
|
||||
// 需要兼容
|
||||
};
|
||||
return OakComponentWrapper;
|
||||
}(react_1.default.PureComponent));
|
||||
// 可能有问题,by Xc
|
||||
Object.assign(OakComponentWrapper, makeMiniprogramCompatibleFunctions());
|
||||
return (0, web_1.withRouter)(OakComponentWrapper, true);
|
||||
}
|
||||
exports.createComponent = createComponent;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="wechat-miniprogram" />
|
||||
import React from 'react';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature } from './types/Feature';
|
||||
import { OakComponentOption } from './types/Page2';
|
||||
export declare function createComponent<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, Proj extends ED[T]['Selection']['data'], FormedData extends Record<string, any>, IsList extends boolean, TData extends Record<string, any> = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends Record<string, Function> = {}>(option: OakComponentOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>): React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createComponent = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
||||
/// <reference path="../node_modules/@types/wechat-miniprogram/index.d.ts" />
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var react_1 = tslib_1.__importDefault(require("react"));
|
||||
var web_1 = require("./platforms/web");
|
||||
var lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
var page_common2_1 = require("./page.common2");
|
||||
var OakComponentBase = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(OakComponentBase, _super);
|
||||
function OakComponentBase() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
OakComponentBase.prototype.subscribe = function () {
|
||||
page_common2_1.subscribe.call(this);
|
||||
};
|
||||
OakComponentBase.prototype.unsubscribe = function () {
|
||||
page_common2_1.unsubscribe.call(this);
|
||||
};
|
||||
OakComponentBase.prototype.onPathSet = function () {
|
||||
page_common2_1.onPathSet.call(this, this.option);
|
||||
};
|
||||
OakComponentBase.prototype.triggerEvent = function (name, detail, options) {
|
||||
};
|
||||
OakComponentBase.prototype.sub = function (type, callback) {
|
||||
this.features.eventBus.sub(type, callback);
|
||||
};
|
||||
OakComponentBase.prototype.unsub = function (type, callback) {
|
||||
this.features.eventBus.unsub(type, callback);
|
||||
};
|
||||
OakComponentBase.prototype.pub = function (type, options) {
|
||||
this.features.eventBus.pub(type, options);
|
||||
};
|
||||
OakComponentBase.prototype.unsubAll = function (type) {
|
||||
this.features.eventBus.unsubAll(type);
|
||||
};
|
||||
OakComponentBase.prototype.save = function (key, item) {
|
||||
this.features.localStorage.save(key, item);
|
||||
};
|
||||
OakComponentBase.prototype.load = function (key) {
|
||||
return this.features.localStorage.load(key);
|
||||
};
|
||||
OakComponentBase.prototype.clear = function () {
|
||||
this.features.localStorage.clear();
|
||||
};
|
||||
OakComponentBase.prototype.resolveInput = function (input, keys) {
|
||||
var currentTarget = input.currentTarget, target = input.target;
|
||||
var value = Object.assign({}, currentTarget, target).value;
|
||||
var dataset = currentTarget.dataset;
|
||||
var result = {
|
||||
dataset: dataset,
|
||||
value: value,
|
||||
};
|
||||
if (keys) {
|
||||
keys.forEach(function (k) {
|
||||
var _a;
|
||||
return Object.assign(result, (_a = {},
|
||||
_a[k] = target[k],
|
||||
_a));
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
OakComponentBase.prototype.setNotification = function (data) {
|
||||
this.features.notification.setNotification(data);
|
||||
};
|
||||
OakComponentBase.prototype.consumeNotification = function () {
|
||||
return this.features.notification.consumeNotification();
|
||||
};
|
||||
OakComponentBase.prototype.setMessage = function (data) {
|
||||
this.features.message.setMessage(data);
|
||||
};
|
||||
OakComponentBase.prototype.consumeMessage = function () {
|
||||
return this.features.message.consumeMessage();
|
||||
};
|
||||
OakComponentBase.prototype.reRender = function (extra) {
|
||||
return page_common2_1.reRender.call(this, this.option, extra);
|
||||
};
|
||||
OakComponentBase.prototype.navigateTo = function (options, state, disableNamespace) {
|
||||
var url = options.url, rest = tslib_1.__rest(options, ["url"]);
|
||||
var url2 = url.includes('?')
|
||||
? url.concat(this.state.oakFullpath
|
||||
? "&oakFrom=".concat(this.state.oakFullpath)
|
||||
: '')
|
||||
: url.concat(this.state.oakFullpath ? "?oakFrom=".concat(this.state.oakFullpath) : '');
|
||||
for (var param in rest) {
|
||||
var param2 = param;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += "".concat(url2.includes('?') ? '&' : '?').concat(param, "=").concat(typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2]));
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: false, state: state });
|
||||
};
|
||||
OakComponentBase.prototype.navigateBack = function (option) {
|
||||
var _this = this;
|
||||
var delta = (option || {}).delta;
|
||||
return new Promise(function (resolve, reject) {
|
||||
try {
|
||||
_this.props.navigate(delta || -1);
|
||||
resolve(undefined);
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.redirectTo = function (options, state, disableNamespace) {
|
||||
var url = options.url, rest = tslib_1.__rest(options, ["url"]);
|
||||
var url2 = url.includes('?')
|
||||
? url.concat(this.state.oakFullpath
|
||||
? "&oakFrom=".concat(this.state.oakFullpath)
|
||||
: '')
|
||||
: url.concat(this.state.oakFullpath
|
||||
? "?oakFrom=".concat(this.state.oakFullpath)
|
||||
: '');
|
||||
for (var param in rest) {
|
||||
var param2 = param;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += "".concat(url2.includes('?') ? '&' : '?').concat(param, "=").concat(typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2]));
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: true, state: state });
|
||||
};
|
||||
OakComponentBase.prototype.setProps = function (props, usingState) {
|
||||
var url = window.location.pathname;
|
||||
if (usingState) {
|
||||
return this.props.navigate(url, { replace: true, state: props });
|
||||
}
|
||||
else {
|
||||
// 这里nodejs的url用不了,先简单写一个
|
||||
var url2 = void 0;
|
||||
var search = window.location.search;
|
||||
if (!search) {
|
||||
var search_1 = '';
|
||||
for (var k in props) {
|
||||
if (search_1) {
|
||||
search_1 + '&';
|
||||
}
|
||||
if (props[k] !== undefined) {
|
||||
search_1 += "".concat(k, "=").concat(typeof props[k] === 'string' ? props[k] : JSON.stringify(props[k]));
|
||||
}
|
||||
}
|
||||
url2 = "".concat(url, "?").concat(search_1);
|
||||
}
|
||||
else {
|
||||
(0, assert_1.default)(search.startsWith('?'));
|
||||
var searchParams = search.slice(1).split('&');
|
||||
var _loop_1 = function (k) {
|
||||
var origin_1 = searchParams.find(function (ele) { return ele.startsWith("".concat(k, "=")); });
|
||||
if (origin_1) {
|
||||
var idx = searchParams.indexOf(origin_1);
|
||||
searchParams.splice(idx, 1);
|
||||
searchParams.push("".concat(k, "=").concat(typeof props[k] === 'string' ? props[k] : JSON.stringify(props[k])));
|
||||
}
|
||||
else {
|
||||
searchParams.push("".concat(k, "=").concat(typeof props[k] === 'string' ? props[k] : JSON.stringify(props[k])));
|
||||
}
|
||||
};
|
||||
for (var k in props) {
|
||||
_loop_1(k);
|
||||
}
|
||||
url2 = "".concat(url, "?").concat(searchParams.join('&'));
|
||||
}
|
||||
return this.props.navigate(url2, { replace: true });
|
||||
}
|
||||
};
|
||||
OakComponentBase.prototype.addOperation = function (operation, beforeExecute, afterExecute) {
|
||||
return this.features.runningTree.addOperation(this.state.oakFullpath, operation, beforeExecute, afterExecute);
|
||||
};
|
||||
OakComponentBase.prototype.cleanOperation = function () {
|
||||
return this.features.runningTree.clean(this.state.oakFullpath);
|
||||
};
|
||||
OakComponentBase.prototype.t = function (key, params) {
|
||||
return this.props.t(key, params);
|
||||
};
|
||||
OakComponentBase.prototype.callPicker = function (attr, params) {
|
||||
if (params === void 0) { params = {}; }
|
||||
return page_common2_1.callPicker.call(this, attr, params);
|
||||
};
|
||||
OakComponentBase.prototype.execute = function () {
|
||||
return page_common2_1.execute.call(this);
|
||||
};
|
||||
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.refresh = function () {
|
||||
return page_common2_1.refresh.call(this);
|
||||
};
|
||||
OakComponentBase.prototype.setUpdateData = function (attr, data) {
|
||||
return page_common2_1.setUpdateData.call(this, attr, data);
|
||||
};
|
||||
OakComponentBase.prototype.loadMore = function () {
|
||||
return page_common2_1.loadMore.call(this);
|
||||
};
|
||||
OakComponentBase.prototype.setId = function (id) {
|
||||
return this.features.runningTree.setId(this.state.oakFullpath, id);
|
||||
};
|
||||
OakComponentBase.prototype.setFilters = function (filters) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.setNamedFilters(this.state.oakFullpath, filters)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.getFilters = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var namedFilters, filters;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!this.state.oakFullpath) return [3 /*break*/, 2];
|
||||
namedFilters = this.features.runningTree.getNamedFilters(this.state.oakFullpath);
|
||||
return [4 /*yield*/, Promise.all(namedFilters.map(function (_a) {
|
||||
var filter = _a.filter;
|
||||
if (typeof filter === 'function') {
|
||||
return filter();
|
||||
}
|
||||
return filter;
|
||||
}))];
|
||||
case 1:
|
||||
filters = _a.sent();
|
||||
return [2 /*return*/, filters];
|
||||
case 2: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.getFilterByName = function (name) {
|
||||
if (this.state.oakFullpath) {
|
||||
var filter = this.features.runningTree.getNamedFilterByName(this.state.oakFullpath, name);
|
||||
if (filter === null || filter === void 0 ? void 0 : filter.filter) {
|
||||
if (typeof filter.filter === 'function') {
|
||||
return filter.filter();
|
||||
}
|
||||
return filter.filter;
|
||||
}
|
||||
}
|
||||
};
|
||||
OakComponentBase.prototype.addNamedFilter = function (namedFilter, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.addNamedFilter(this.state.oakFullpath, namedFilter, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.removeNamedFilter = function (namedFilter, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.removeNamedFilter(this.state.oakFullpath, namedFilter, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.removeNamedFilterByName = function (name, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.removeNamedFilterByName(this.state.oakFullpath, name, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.setNamedSorters = function (namedSorters) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.setNamedSorters(this.state.oakFullpath, namedSorters)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.getSorters = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var namedSorters, sorters;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!this.state.oakFullpath) return [3 /*break*/, 2];
|
||||
namedSorters = this.features.runningTree.getNamedSorters(this.state.oakFullpath);
|
||||
return [4 /*yield*/, Promise.all(namedSorters.map(function (_a) {
|
||||
var sorter = _a.sorter;
|
||||
if (typeof sorter === 'function') {
|
||||
return sorter();
|
||||
}
|
||||
return sorter;
|
||||
}))];
|
||||
case 1:
|
||||
sorters = (_a.sent()).filter(function (ele) { return !!ele; });
|
||||
return [2 /*return*/, sorters];
|
||||
case 2: return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.getSorterByName = function (name) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var sorter;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
if (this.state.oakFullpath) {
|
||||
sorter = this.features.runningTree.getNamedSorterByName(this.state.oakFullpath, name);
|
||||
if (sorter === null || sorter === void 0 ? void 0 : sorter.sorter) {
|
||||
if (typeof sorter.sorter === 'function') {
|
||||
return [2 /*return*/, sorter.sorter()];
|
||||
}
|
||||
return [2 /*return*/, sorter.sorter];
|
||||
}
|
||||
}
|
||||
return [2 /*return*/];
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.addNamedSorter = function (namedSorter, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.addNamedSorter(this.state.oakFullpath, namedSorter, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.removeNamedSorter = function (namedSorter, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.removeNamedSorter(this.state.oakFullpath, namedSorter, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.removeNamedSorterByName = function (name, refresh) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.features.runningTree.removeNamedSorterByName(this.state.oakFullpath, name, refresh)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
OakComponentBase.prototype.getPagination = function () {
|
||||
if (this.state.oakFullpath) {
|
||||
return this.features.runningTree.getPagination(this.state.oakFullpath);
|
||||
}
|
||||
};
|
||||
OakComponentBase.prototype.setPageSize = function (pageSize) {
|
||||
this.features.runningTree.setPageSize(this.state.oakFullpath, pageSize);
|
||||
};
|
||||
OakComponentBase.prototype.setCurrentPage = function (currentPage) {
|
||||
(0, assert_1.default)(currentPage !== 0);
|
||||
if (this.state.oakEntity && this.state.oakFullpath) {
|
||||
this.features.runningTree.setCurrentPage(this.state.oakFullpath, currentPage);
|
||||
}
|
||||
};
|
||||
return OakComponentBase;
|
||||
}(react_1.default.PureComponent));
|
||||
function translateObservers(observers) {
|
||||
return {
|
||||
fn: function (prevProps, prevState) {
|
||||
var e_1, _a, e_2, _b;
|
||||
var _c = this, state = _c.state, props = _c.props;
|
||||
for (var obs in observers) {
|
||||
var keys = obs.split(',').map(function (ele) { return ele.trim(); });
|
||||
var changed = false;
|
||||
try {
|
||||
for (var keys_1 = (e_1 = void 0, tslib_1.__values(keys)), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
|
||||
var k = keys_1_1.value;
|
||||
if (k.includes('*')) {
|
||||
throw new Error('web模式下带*的observer通配符暂不支持');
|
||||
}
|
||||
if ((0, lodash_1.get)(props, k) !== (0, lodash_1.get)(prevProps, k) ||
|
||||
(0, lodash_1.get)(state, k) !== (0, lodash_1.get)(prevState, k)) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
var args = [];
|
||||
if (changed) {
|
||||
try {
|
||||
for (var keys_2 = (e_2 = void 0, tslib_1.__values(keys)), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
|
||||
var k = keys_2_1.value;
|
||||
args.push((0, lodash_1.get)(props, k) === undefined
|
||||
? (0, lodash_1.get)(state, k)
|
||||
: (0, lodash_1.get)(props, k));
|
||||
}
|
||||
}
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (keys_2_1 && !keys_2_1.done && (_b = keys_2.return)) _b.call(keys_2);
|
||||
}
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
}
|
||||
observers[obs].apply(this, args);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
var DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
function createComponent(option, features, exceptionRouterDict) {
|
||||
var _a = option, data = _a.data, projection = _a.projection, properties = _a.properties, entity = _a.entity, methods = _a.methods, lifetimes = _a.lifetimes, observers = _a.observers, render = _a.render, path = _a.path;
|
||||
var fn = translateObservers(observers).fn;
|
||||
var OakComponentWrapper = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(OakComponentWrapper, _super);
|
||||
function OakComponentWrapper(props) {
|
||||
var _a;
|
||||
var _this = _super.call(this, props) || this;
|
||||
_this.features = features;
|
||||
_this.option = option;
|
||||
_this.isReachBottom = false;
|
||||
_this.scrollEvent = function () {
|
||||
_this.checkReachBottom();
|
||||
};
|
||||
if (methods) {
|
||||
for (var m in methods) {
|
||||
Object.assign(_this, (_a = {},
|
||||
_a[m] = methods[m].bind(_this),
|
||||
_a));
|
||||
}
|
||||
}
|
||||
_this.state = Object.assign({}, data, {
|
||||
oakLoading: false,
|
||||
oakLoadingMore: false,
|
||||
oakIsReady: false,
|
||||
oakExeucting: false,
|
||||
oakDirty: false,
|
||||
});
|
||||
(lifetimes === null || lifetimes === void 0 ? void 0 : lifetimes.created) && lifetimes.created.call(_this);
|
||||
return _this;
|
||||
}
|
||||
// todo 这里还需要根据path和location来判断自己是不是page
|
||||
OakComponentWrapper.prototype.iAmThePage = function () {
|
||||
return !!path;
|
||||
};
|
||||
OakComponentWrapper.prototype.supportPullDownRefresh = function () {
|
||||
return this.props.width === 'xs' && this.iAmThePage();
|
||||
};
|
||||
OakComponentWrapper.prototype.registerPageScroll = function () {
|
||||
var _a = this.props.useBodyScroll, useBodyScroll = _a === void 0 ? false : _a;
|
||||
if (useBodyScroll) {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
this.lv && this.lv.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
};
|
||||
OakComponentWrapper.prototype.unregisterPageScroll = function () {
|
||||
var _a = this.props.useBodyScroll, useBodyScroll = _a === void 0 ? false : _a;
|
||||
if (useBodyScroll) {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
this.lv && this.lv.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
};
|
||||
OakComponentWrapper.prototype.checkReachBottom = function () {
|
||||
if (!this.supportPullDownRefresh()) {
|
||||
return;
|
||||
}
|
||||
var isCurrentReachBottom = document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
if (!this.isReachBottom && isCurrentReachBottom && option.isList) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
this.loadMore();
|
||||
return;
|
||||
}
|
||||
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);
|
||||
};
|
||||
OakComponentWrapper.prototype.componentWillUnmount = function () {
|
||||
this.state.oakFullpath && 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);
|
||||
};
|
||||
OakComponentWrapper.prototype.render = function () {
|
||||
var _this = this;
|
||||
var Render = render.call(this);
|
||||
var oakLoading = this.state.oakLoading;
|
||||
var _a = this.props.useBodyScroll, useBodyScroll = _a === void 0 ? false : _a;
|
||||
if (this.supportPullDownRefresh()) {
|
||||
var child = react_1.default.cloneElement((0, jsx_runtime_1.jsx)(web_1.PullToRefresh, { onRefresh: function () {
|
||||
_this.refresh();
|
||||
}, refreshing: oakLoading, distanceToRefresh: DEFAULT_REACH_BOTTOM_DISTANCE, indicator: {
|
||||
activate: this.t('common:ptrActivate'),
|
||||
deactivate: this.t('common:ptrDeactivate'),
|
||||
release: this.t('common:ptrRelease'),
|
||||
finish: this.t('common:ptrFinish'),
|
||||
} }), {
|
||||
getScrollContainer: function () { return useBodyScroll ? document.body : _this.lv; },
|
||||
}, Render);
|
||||
return useBodyScroll ? (child) : ((0, jsx_runtime_1.jsx)("div", tslib_1.__assign({ ref: function (el) { return (_this.lv = el); }, style: { height: '100%', overflow: 'auto' } }, { children: child })));
|
||||
}
|
||||
return Render;
|
||||
};
|
||||
return OakComponentWrapper;
|
||||
}(OakComponentBase));
|
||||
;
|
||||
return (0, web_1.withRouter)(OakComponentWrapper, false, option.path);
|
||||
}
|
||||
exports.createComponent = createComponent;
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
var Interpreter = (function (r) {
|
||||
var o = '';
|
||||
function i(r, n) {
|
||||
return r
|
||||
? 'string' == typeof r
|
||||
? r
|
||||
: r
|
||||
.reduce(function (r, t) {
|
||||
return r.concat([
|
||||
(function (n, e) {
|
||||
if (((e = e || {}), 'string' == typeof n))
|
||||
return n;
|
||||
{
|
||||
var r, t, u;
|
||||
if (n[2] && 'object' == typeof n[2])
|
||||
return (
|
||||
(r = Object.keys(n[2]).reduce(
|
||||
function (r, t) {
|
||||
return (
|
||||
(r[t] = i(
|
||||
n[2][t],
|
||||
e
|
||||
)),
|
||||
r
|
||||
);
|
||||
},
|
||||
{}
|
||||
)),
|
||||
(t = r[e[0]]),
|
||||
void 0 !== (u = e[n[0]])
|
||||
? r[u.toString()] ||
|
||||
r.other ||
|
||||
o
|
||||
: t || r.other || o
|
||||
);
|
||||
}
|
||||
if ('object' == typeof n && 0 < n.length)
|
||||
return (function r(t, n, e) {
|
||||
void 0 === e && (e = 0);
|
||||
if (!n || !t || t.length <= 0)
|
||||
return '';
|
||||
n = n[t[e]];
|
||||
if ('string' == typeof n) return n;
|
||||
if ('number' == typeof n)
|
||||
return n.toString();
|
||||
if (!n)
|
||||
return '{'.concat(
|
||||
t.join('.'),
|
||||
'}'
|
||||
);
|
||||
return r(t, n, ++e);
|
||||
})(n[0].split('.'), e, 0);
|
||||
return '';
|
||||
})(t, n),
|
||||
]);
|
||||
}, [])
|
||||
.join('')
|
||||
: o;
|
||||
}
|
||||
function c(r, t, n) {
|
||||
return (
|
||||
('object' == typeof r &&
|
||||
((t = t).constructor && 'Array' === t.constructor
|
||||
? t
|
||||
: t
|
||||
.replace(getRegExp('\[', 'ig'), '.')
|
||||
.replace(getRegExp('\]', 'ig'), '')
|
||||
.split('.')
|
||||
).reduce(function (r, t) {
|
||||
return (r || {})[t];
|
||||
}, r)) ||
|
||||
n
|
||||
);
|
||||
}
|
||||
function f(r) {
|
||||
var t = r;
|
||||
return (t =
|
||||
r && -1 !== r.indexOf(':')
|
||||
? r.replace(getRegExp(':', 'ig'), '.')
|
||||
: t);
|
||||
}
|
||||
function g(r, t, n) {
|
||||
var e = f(n),
|
||||
r = r[t];
|
||||
return (r && (r[e] || c(r, e))) || n;
|
||||
}
|
||||
return (
|
||||
(r.getMessageInterpreter = function () {
|
||||
function u(r, t, n, e) {
|
||||
return i(
|
||||
(function (r, t, n, e) {
|
||||
var u = f(r);
|
||||
if (!(n = t[n])) return g(t, e, r);
|
||||
var o = n[u];
|
||||
return (o = o || c(n, u)) ? o : g(t, e, r);
|
||||
})(r, e, n, n),
|
||||
t
|
||||
);
|
||||
}
|
||||
return function (r, t, n, e) {
|
||||
return 3 === arguments.length
|
||||
? u(r, null, t, n)
|
||||
: 4 === arguments.length
|
||||
? u(r, t, n, e)
|
||||
: '';
|
||||
};
|
||||
}),
|
||||
r
|
||||
);
|
||||
})({});
|
||||
|
|
@ -41,6 +41,9 @@ function Action(target, propertyName, descriptor) {
|
|||
switch (_a.label) {
|
||||
case 0:
|
||||
mActionStackDepth++;
|
||||
if (mActionStackDepth > 20) {
|
||||
console.error("action[".concat(method.name, "]\u8C03\u7528\u7684\u5C42\u7EA7\u8D85\u8FC7\u4E8620\uFF0C\u8BF7\u68C0\u67E5\u662F\u5426\u5B58\u5728\u65E0\u9650\u9012\u5F52"));
|
||||
}
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntity
|
|||
execute: (action: ED[T]['Action'], legalExceptions?: Array<string>, path?: string) => Promise<DeduceOperation<ED[T]['Schema']> | DeduceOperation<ED[T]['Schema']>[] | undefined>;
|
||||
};
|
||||
export declare type OakListComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
pushNode: (path?: string, options?: Pick<CreateNodeOptions<ED, keyof ED>, 'updateData' | 'beforeExecute' | 'afterExecute'>) => Promise<void>;
|
||||
pushNode: (path?: string, options?: CreateNodeOptions<ED, keyof ED>) => Promise<void>;
|
||||
removeNode: (parent: string, path: string) => Promise<void>;
|
||||
setFilters: (filters: NamedFilterItem<ED, T>[]) => Promise<void>;
|
||||
getFilters: () => Promise<ED[T]['Selection']['filter'][] | undefined>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,195 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
/// <reference types="react" />
|
||||
import { Aspect, Context, EntityDict, DeduceSorterItem, SelectRowShape, CheckerType } from "oak-domain/lib/types";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Feature } from './Feature';
|
||||
import { Pagination } from "./Pagination";
|
||||
import { BasicFeatures } from "../features";
|
||||
import { NamedFilterItem, NamedSorterItem } from './NamedCondition';
|
||||
import { NotificationProps } from './Notification';
|
||||
import { MessageProps } from './Message';
|
||||
declare type RowSelected<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Proj extends ED[T]['Selection']['data'] = Required<ED[T]['Selection']['data']>> = SelectRowShape<ED[T]['Schema'], Proj> | undefined;
|
||||
interface ComponentOption<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, Proj extends ED[T]['Selection']['data'], FormedData extends Record<string, any>, IsList extends boolean, TProperty extends WechatMiniprogram.Component.PropertyOption = {}> {
|
||||
entity?: T;
|
||||
path?: string;
|
||||
isList: IsList;
|
||||
projection?: Proj | ((options: {
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
|
||||
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
|
||||
state: Record<string, any>;
|
||||
}) => Promise<Proj>);
|
||||
append?: boolean;
|
||||
pagination?: Pagination;
|
||||
filters?: Array<{
|
||||
filter: ED[T]['Selection']['filter'] | ((options: {
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
|
||||
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
|
||||
state: Record<string, any>;
|
||||
}) => Promise<ED[T]['Selection']['filter']> | undefined);
|
||||
'#name'?: string;
|
||||
}>;
|
||||
sorters?: Array<{
|
||||
sorter: DeduceSorterItem<ED[T]['Schema']> | ((options: {
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
|
||||
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
|
||||
state: Record<string, any>;
|
||||
}) => Promise<DeduceSorterItem<ED[T]['Schema']>>);
|
||||
'#name'?: string;
|
||||
}>;
|
||||
formData?: (options: {
|
||||
data: IsList extends true ? RowSelected<ED, T, Proj>[] : RowSelected<ED, T, Proj>;
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD;
|
||||
props: Partial<WechatMiniprogram.Component.PropertyOptionToData<TProperty>>;
|
||||
}) => Promise<FormedData>;
|
||||
ns?: T | T[];
|
||||
}
|
||||
export declare type MiniprogramStyleMethods = {
|
||||
animate(selector: string, keyFrames: WechatMiniprogram.Component.KeyFrame[], duration: number, callback?: () => void): void;
|
||||
clearAnimation(selector: string, options?: WechatMiniprogram.Component.ClearAnimationOptions, callback?: () => void): void;
|
||||
triggerEvent: <DetailType = any>(name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption) => void;
|
||||
};
|
||||
export declare type ComponentProps<IsList extends boolean, TProperty extends WechatMiniprogram.Component.PropertyOption> = IsList extends true ? WechatMiniprogram.Component.PropertyOptionToData<OakListComponentProperties & OakComponentProperties & TProperty> : WechatMiniprogram.Component.PropertyOptionToData<OakComponentProperties & TProperty>;
|
||||
export declare type ComponentData<ED extends EntityDict & BaseEntityDict, T extends keyof ED, FormedData extends WechatMiniprogram.Component.DataOption, TData extends WechatMiniprogram.Component.DataOption> = TData & FormedData & OakComponentData<ED, T>;
|
||||
export declare type ComponentPublicThisType<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends Record<string, any>, IsList extends boolean, TData extends Record<string, any> = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}> = {
|
||||
features: FD & BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>;
|
||||
state: ComponentData<ED, T, FormedData, TData>;
|
||||
props: ComponentProps<IsList, TProperty>;
|
||||
setState: (data: Partial<ComponentData<ED, T, FormedData, TData>>, callback?: () => void) => void;
|
||||
triggerEvent: <DetailType = any>(name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption) => void;
|
||||
} & TMethod & OakCommonComponentMethods<ED, T> & (IsList extends true ? OakListComponentMethods<ED, T> : {});
|
||||
export declare type ComponentFullThisType<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>> = {
|
||||
features: BasicFeatures<ED, Cxt, CommonAspectDict<ED, Cxt>>;
|
||||
state: OakComponentData<ED, T>;
|
||||
props: ComponentProps<true, {}>;
|
||||
setState: (data: Partial<OakComponentData<ED, T>>, callback?: () => void) => void;
|
||||
triggerEvent: <DetailType = any>(name: string, detail?: DetailType, options?: WechatMiniprogram.Component.TriggerEventOption) => void;
|
||||
} & OakCommonComponentMethods<ED, T> & OakListComponentMethods<ED, T> & OakHiddenComponentMethods;
|
||||
export declare type OakComponentOption<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, Proj extends ED[T]['Selection']['data'], FormedData extends Record<string, any>, IsList extends boolean, TData extends Record<string, any>, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends Record<string, Function>> = ComponentOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TProperty> & Partial<{
|
||||
data?: TData;
|
||||
properties: TProperty;
|
||||
methods: TMethod;
|
||||
lifetimes: {
|
||||
created?(): void;
|
||||
attached?(): void;
|
||||
ready?(): void;
|
||||
moved?(): void;
|
||||
detached?(): void;
|
||||
error?(err: Error): void;
|
||||
show?(): void;
|
||||
hide?(): void;
|
||||
};
|
||||
observers: Record<string, (...args: any[]) => any>;
|
||||
}> & Partial<{
|
||||
wechatMp: {
|
||||
externalClasses?: string[];
|
||||
options?: Partial<WechatMiniprogram.Component.ComponentOptions> | undefined;
|
||||
};
|
||||
}> & ThisType<ComponentPublicThisType<ED, T, Cxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod>>;
|
||||
export declare type OakComponentProperties = {
|
||||
oakEntity: StringConstructor;
|
||||
oakPath: StringConstructor;
|
||||
oakId: StringConstructor;
|
||||
oakProjection: StringConstructor;
|
||||
oakFrom: StringConstructor;
|
||||
oakParentEntity: StringConstructor;
|
||||
enablePullDownRefresh: BooleanConstructor;
|
||||
};
|
||||
export declare type OakListComponentProperties = {
|
||||
oakFilters: StringConstructor;
|
||||
oakSorters: StringConstructor;
|
||||
oakIsPicker: BooleanConstructor;
|
||||
};
|
||||
export declare type OakNavigateToParameters<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
oakId?: string;
|
||||
oakEntity?: T;
|
||||
oakPath?: string;
|
||||
oakParent?: string;
|
||||
oakProjection?: ED[T]['Selection']['data'];
|
||||
oakSorters?: Array<NamedSorterItem<ED, T>>;
|
||||
oakFilters?: Array<NamedFilterItem<ED, T>>;
|
||||
oakIsPicker?: boolean;
|
||||
[k: string]: any;
|
||||
};
|
||||
export declare type OakHiddenComponentMethods = {
|
||||
subscribed?: () => void;
|
||||
subscribe: () => void;
|
||||
unsubscribe: () => void;
|
||||
};
|
||||
export declare type OakCommonComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
sub: (type: string, callback: Function) => void;
|
||||
unsub: (type: string, callback: Function) => void;
|
||||
pub: (type: string, options?: any) => void;
|
||||
unsubAll: (type: string) => void;
|
||||
save: (key: string, item: any) => void;
|
||||
load: (key: string) => any;
|
||||
clear: () => void;
|
||||
resolveInput: <K extends string>(input: any, keys?: K[]) => {
|
||||
dataset?: Record<string, any>;
|
||||
value?: string;
|
||||
} & {
|
||||
[k in K]?: any;
|
||||
};
|
||||
setNotification: (data: NotificationProps) => void;
|
||||
consumeNotification: () => NotificationProps | undefined;
|
||||
setMessage: (data: MessageProps) => void;
|
||||
consumeMessage: () => MessageProps | undefined;
|
||||
reRender: (extra?: Record<string, any>) => Promise<void>;
|
||||
navigateTo: <T2 extends keyof ED>(options: {
|
||||
url: string;
|
||||
} & OakNavigateToParameters<ED, T2>, state?: Record<string, any>, disableNamespace?: boolean) => Promise<void>;
|
||||
navigateBack: (option?: {
|
||||
delta: number;
|
||||
}) => Promise<void>;
|
||||
redirectTo: <T2 extends keyof ED>(options: Parameters<typeof wx.redirectTo>[0] & OakNavigateToParameters<ED, T2>, state?: Record<string, any>, disableNamespace?: boolean) => Promise<void>;
|
||||
setProps: (props: Record<string, any>, usingState?: true) => void;
|
||||
resetUpdateData: () => void;
|
||||
addOperation: (operation: Omit<ED[T]['Operation'], 'id'>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>) => Promise<void>;
|
||||
cleanOperation: () => void;
|
||||
t(key: string, params?: object): string;
|
||||
callPicker: (attr: string, params: Record<string, any>) => void;
|
||||
execute: () => Promise<void>;
|
||||
checkOperation: (ntity: T, action: ED[T]['Action'], filter?: ED[T]['Update']['filter'], checkerTypes?: CheckerType[]) => Promise<boolean>;
|
||||
tryExecute: () => Promise<void>;
|
||||
refresh: (extra?: any) => Promise<void>;
|
||||
setUpdateData: (data: string, attr: any) => Promise<void>;
|
||||
};
|
||||
export declare type OakListComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
loadMore: () => Promise<void>;
|
||||
setFilters: (filters: NamedFilterItem<ED, T>[]) => Promise<void>;
|
||||
getFilters: () => Promise<ED[T]['Selection']['filter'][] | undefined>;
|
||||
getFilterByName: (name: string) => Promise<ED[T]['Selection']['filter']> | undefined;
|
||||
addNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => Promise<void>;
|
||||
removeNamedFilter: (filter: NamedFilterItem<ED, T>, refresh?: boolean) => Promise<void>;
|
||||
removeNamedFilterByName: (name: string, refresh?: boolean) => Promise<void>;
|
||||
setNamedSorters: (sorters: NamedSorterItem<ED, T>[]) => Promise<void>;
|
||||
getSorters: () => Promise<ED[T]['Selection']['sorter'] | undefined>;
|
||||
getSorterByName: (name: string) => Promise<DeduceSorterItem<ED[T]['Schema']> | undefined>;
|
||||
addNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => Promise<void>;
|
||||
removeNamedSorter: (filter: NamedSorterItem<ED, T>, refresh?: boolean) => Promise<void>;
|
||||
removeNamedSorterByName: (name: string, refresh?: boolean) => Promise<void>;
|
||||
getPagination: () => Pagination | undefined;
|
||||
setPageSize: (pageSize: number) => void;
|
||||
setCurrentPage: (current: number) => void;
|
||||
};
|
||||
declare type ComponentOnPropsChangeOption = {
|
||||
path?: string;
|
||||
parent?: string;
|
||||
};
|
||||
export declare type OakComponentOnlyMethods = {
|
||||
onPropsChanged: (options: ComponentOnPropsChangeOption) => void;
|
||||
registerReRender: () => void;
|
||||
setOakActions: () => void;
|
||||
};
|
||||
export declare type OakComponentData<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
oakExecuting: boolean;
|
||||
oakFocused: object;
|
||||
oakDirty: boolean;
|
||||
oakLoading: boolean;
|
||||
oakLoadingMore: boolean;
|
||||
oakEntity: T;
|
||||
oakIsReady: boolean;
|
||||
oakFullpath: string;
|
||||
};
|
||||
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 {};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
;
|
||||
|
|
@ -85,7 +85,7 @@ export class Cache<
|
|||
selection: ED[T]['Selection'],
|
||||
option?: OP
|
||||
) {
|
||||
reinforceSelection(this.cacheStore!.getSchema(), entity, selection);
|
||||
// reinforceSelection(this.cacheStore!.getSchema(), entity, selection);
|
||||
const { result } = await this.getAspectWrapper().exec('count', {
|
||||
entity,
|
||||
selection,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { cloneDeep, pull, set, unset } from "oak-domain/lib/utils/lodash";
|
||||
import { cloneDeep, pull, set, unset, merge } from "oak-domain/lib/utils/lodash";
|
||||
import { combineFilters, contains, repel, same } from "oak-domain/lib/store/filter";
|
||||
import { createOperationsFromModies } from 'oak-domain/lib/store/modi';
|
||||
import { judgeRelation } from "oak-domain/lib/store/relation";
|
||||
|
|
@ -31,6 +31,7 @@ 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
|
||||
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED, Cxt, AD>,
|
||||
projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>),
|
||||
|
|
@ -45,12 +46,35 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
|
|||
this.loadingMore = false;
|
||||
this.executing = false;
|
||||
this.operations = [];
|
||||
this.modiIds = [];
|
||||
}
|
||||
|
||||
getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
protected abstract getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string;
|
||||
|
||||
/**
|
||||
* 这个函数从某个结点向父亲查询,看所在路径上是否有需要被应用的modi
|
||||
*/
|
||||
getModiIds(child: Node<ED, keyof ED, Cxt, AD>): string[] {
|
||||
const childPath = this.getChildPath(child);
|
||||
if (childPath.includes(':')) {
|
||||
const { modiIds } = this;
|
||||
// 如果是需要modi的路径,在这里应该就可以返回了,目前应该不存在modi嵌套modi
|
||||
return modiIds;
|
||||
}
|
||||
const { toModi } = this.schema[this.entity];
|
||||
if (toModi) {
|
||||
// 如果这就是一个toModi的对象,则不用再向上查找了
|
||||
return [];
|
||||
}
|
||||
if (this.parent) {
|
||||
return this.parent.getModiIds(this);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
setDirty() {
|
||||
if (!this.dirty) {
|
||||
|
|
@ -85,8 +109,8 @@ abstract class Node<ED extends EntityDict & BaseEntityDict, T extends keyof ED,
|
|||
return this.parent;
|
||||
}
|
||||
|
||||
async getProjection() {
|
||||
return typeof this.projection === 'function' ? await this.projection() : this.projection;
|
||||
protected async getProjection() {
|
||||
return typeof this.projection === 'function' ? await this.projection() : cloneDeep(this.projection);
|
||||
}
|
||||
|
||||
protected judgeRelation(attr: string) {
|
||||
|
|
@ -310,6 +334,18 @@ class ListNode<
|
|||
|
||||
private syncHandler: (records: OpRecord<ED>[]) => Promise<void>;
|
||||
|
||||
protected getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string {
|
||||
let idx = 0;
|
||||
for (const child2 of this.children) {
|
||||
if (child === child2) {
|
||||
return `${idx}`;
|
||||
}
|
||||
idx ++;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
async onCacheSync(records: OpRecord<ED>[]): Promise<void> {
|
||||
// 只需要处理insert
|
||||
if (this.loading) {
|
||||
|
|
@ -342,7 +378,7 @@ class ListNode<
|
|||
if (createdIds.length > 0) {
|
||||
const currentIds = this.ids;
|
||||
|
||||
const { sorter, filters } = await this.constructSelection();
|
||||
const { sorter, filters } = await this.constructSelection(true);
|
||||
filters.push({
|
||||
id: {
|
||||
$in: currentIds.concat(createdIds),
|
||||
|
|
@ -560,6 +596,31 @@ 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<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
}>;
|
||||
operations.push(...this.operations.map(
|
||||
ele => ({
|
||||
entity: this.entity,
|
||||
operation: ele.oper,
|
||||
})
|
||||
));
|
||||
|
||||
const { result } = await this.cache.tryRedoOperationsThenSelect(this.entity, {
|
||||
data: projection,
|
||||
filter: {
|
||||
|
|
@ -567,12 +628,7 @@ class ListNode<
|
|||
$in: ids,
|
||||
}
|
||||
} as any,
|
||||
}, this.operations.map(
|
||||
ele => ({
|
||||
entity: this.entity,
|
||||
operation: ele.oper,
|
||||
})
|
||||
));
|
||||
}, operations);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -612,10 +668,19 @@ class ListNode<
|
|||
return operations;
|
||||
}
|
||||
|
||||
private async constructSelection() {
|
||||
async getProjection(): Promise<ED[T]['Selection']['data']> {
|
||||
const projection = await super.getProjection();
|
||||
if (this.children.length > 0) {
|
||||
const subProjection = await this.children[0].getProjection();
|
||||
return merge(projection, subProjection);
|
||||
}
|
||||
return projection;
|
||||
}
|
||||
|
||||
async constructSelection(withParent?: true) {
|
||||
const { filters, sorters } = this;
|
||||
const proj = await this.getProjection();
|
||||
assert(proj, "取数据时找不到projection信息");
|
||||
const data = await this.getProjection();
|
||||
assert(data, "取数据时找不到projection信息");
|
||||
const sorterArr = (
|
||||
await Promise.all(
|
||||
sorters.map(async (ele) => {
|
||||
|
|
@ -638,11 +703,15 @@ class ListNode<
|
|||
})
|
||||
);
|
||||
|
||||
const filterOfParent = (this.parent as SingleNode<ED, keyof ED, Cxt, AD>)?.getOtmFilter<T>(this);
|
||||
filterArr.push(filterOfParent as any);
|
||||
if (withParent) {
|
||||
const filterOfParent = (this.parent as SingleNode<ED, keyof ED, Cxt, AD>)?.getOtmFilter<T>(this);
|
||||
if (filterOfParent) {
|
||||
filterArr.push(filterOfParent as any);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
projection: proj,
|
||||
data,
|
||||
filters: filterArr.filter(ele => !!ele) as ED[T]['Selection']['filter'][],
|
||||
sorter: sorterArr,
|
||||
}
|
||||
|
|
@ -658,7 +727,7 @@ class ListNode<
|
|||
this.loading = true;
|
||||
}
|
||||
const currentPage3 = typeof pageNumber === 'number' ? pageNumber : currentPage;
|
||||
const { projection, filters, sorter } = await this.constructSelection();
|
||||
const { data: projection, filters, sorter } = await this.constructSelection(true);
|
||||
try {
|
||||
const { data, count } = await this.cache.refresh(
|
||||
entity,
|
||||
|
|
@ -746,97 +815,15 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
parent?: Node<ED, keyof ED, Cxt, AD>) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.children = {};
|
||||
}
|
||||
|
||||
const ownKeys: string[] = [];
|
||||
const attrs = Object.keys(projectionShape);
|
||||
const { toModi } = schema[entity];
|
||||
attrs.forEach(
|
||||
(attr) => {
|
||||
const proj = typeof projection === 'function' ? async () => {
|
||||
const projection2 = await projection();
|
||||
return projection2[attr];
|
||||
} : projection[attr];
|
||||
const rel = this.judgeRelation(attr);
|
||||
if (rel === 2) {
|
||||
const node = new SingleNode(attr, this.schema, this.cache, proj, projectionShape[attr], this);
|
||||
Object.assign(this.children, {
|
||||
[attr]: node,
|
||||
});
|
||||
if (toModi && attr !== 'modi$entity') {
|
||||
const node2 = new SingleNode(attr, this.schema, this.cache, proj, projectionShape[attr], this);
|
||||
Object.assign(this.children, {
|
||||
[`${attr}:prev`]: node2,
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'string') {
|
||||
const node = new SingleNode(rel, this.schema, this.cache, proj, projectionShape[attr], this);
|
||||
Object.assign(this.children, {
|
||||
[attr]: node,
|
||||
});
|
||||
if (toModi && attr !== 'modi$entity') {
|
||||
const node2 = new SingleNode(attr, this.schema, this.cache, proj, projectionShape[attr], this);
|
||||
Object.assign(this.children, {
|
||||
[`${attr}:prev`]: node2,
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (typeof rel === 'object' && rel instanceof Array) {
|
||||
const { data: subProjectionShape } = projectionShape[attr] as ED[keyof ED]['Selection'];
|
||||
const proj = typeof projection === 'function' ? async () => {
|
||||
const projection2 = await projection();
|
||||
return projection2[attr].data;
|
||||
} : projection[attr].data;
|
||||
const filter = typeof projection === 'function' ? async () => {
|
||||
const projection2 = await projection();
|
||||
return projection2[attr].filter;
|
||||
} : projection[attr].filter;
|
||||
const sorters = typeof projection === 'function' ? async () => {
|
||||
const projection2 = await projection();
|
||||
return projection2[attr].sorter;
|
||||
} : projection[attr].sorter;
|
||||
const node = new ListNode(rel[0], this.schema, this.cache, proj, subProjectionShape, this);
|
||||
if (filter) {
|
||||
node.addNamedFilter({
|
||||
filter,
|
||||
});
|
||||
}
|
||||
if (sorters && sorters instanceof Array) {
|
||||
// todo 没有处理projection是一个function的case
|
||||
sorters.forEach(
|
||||
ele => node.addNamedSorter({
|
||||
sorter: ele
|
||||
})
|
||||
);
|
||||
}
|
||||
Object.assign(this.children, {
|
||||
[attr]: node,
|
||||
});
|
||||
if (toModi && attr !== 'modi$entity') {
|
||||
const node2 = new ListNode(rel[0], this.schema, this.cache, proj, subProjectionShape, this);
|
||||
if (filter) {
|
||||
node2.addNamedFilter({
|
||||
filter,
|
||||
});
|
||||
}
|
||||
if (sorters && sorters instanceof Array) {
|
||||
// todo 没有处理projection是一个function的case
|
||||
sorters.forEach(
|
||||
ele => node2.addNamedSorter({
|
||||
sorter: ele
|
||||
})
|
||||
);
|
||||
}
|
||||
Object.assign(this.children, {
|
||||
[`${attr}:prev`]: node2,
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
ownKeys.push(attr);
|
||||
}
|
||||
protected getChildPath(child: Node<ED, keyof ED, Cxt, AD>): string {
|
||||
for (const k in this.children) {
|
||||
if (child === this.children[k]) {
|
||||
return k;
|
||||
}
|
||||
);
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
|
|
@ -929,17 +916,36 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
|
||||
async getFreshValue(): Promise<SelectRowShape<ED[T]['Schema'], ED[T]['Selection']['data']>> {
|
||||
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<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
}>;
|
||||
operations.push(...this.operations.map(
|
||||
ele => ({
|
||||
entity: this.entity,
|
||||
operation: ele.oper,
|
||||
})
|
||||
));
|
||||
const { result } = await this.cache.tryRedoOperationsThenSelect(this.entity, {
|
||||
data: projection,
|
||||
filter: {
|
||||
id: this.id,
|
||||
} as any,
|
||||
}, this.operations.map(
|
||||
ele => ({
|
||||
entity: this.entity,
|
||||
operation: ele.oper
|
||||
})
|
||||
));
|
||||
}, operations);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
|
|
@ -999,12 +1005,15 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sliceIdx = ele.indexOf(':');
|
||||
const ele2 = sliceIdx > 0 ? ele.slice(0, sliceIdx) : ele;
|
||||
return {
|
||||
oper: {
|
||||
id: 'dummy', // 因为肯定会被merge掉,所以无所谓了
|
||||
action: 'update',
|
||||
data: {
|
||||
[ele]: subOper,
|
||||
[ele2]: subOper,
|
||||
},
|
||||
filter: {
|
||||
id: this.id,
|
||||
|
|
@ -1041,6 +1050,33 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
return operations;
|
||||
}
|
||||
|
||||
async getProjection() {
|
||||
const projection = await super.getProjection();
|
||||
for (const k in this.children) {
|
||||
if (k.indexOf(':') === -1) {
|
||||
const rel = this.judgeRelation(k);
|
||||
if (rel === 2 || typeof rel === 'string') {
|
||||
const subProjection = await this.children[k].getProjection();
|
||||
Object.assign(projection, {
|
||||
[k]: subProjection,
|
||||
});
|
||||
}
|
||||
else {
|
||||
const child = this.children[k];
|
||||
assert(rel instanceof Array && child instanceof ListNode);
|
||||
const subSelection = await child.constructSelection();
|
||||
const subEntity = child.getEntity();
|
||||
Object.assign(projection, {
|
||||
[k]: Object.assign(subSelection, {
|
||||
$entity: subEntity,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return projection;
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
const projection = await this.getProjection();
|
||||
if (this.id) {
|
||||
|
|
@ -1052,6 +1088,11 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
id: this.id,
|
||||
},
|
||||
} as any);
|
||||
// 对于modi对象,在此缓存
|
||||
if (this.schema[this.entity].toModi) {
|
||||
const { modi$entity } = value;
|
||||
this.modiIds = (modi$entity as Array<{ id: string }>).map(ele => ele.id);
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
catch (err) {
|
||||
|
|
@ -1073,7 +1114,9 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
getOtmFilter<T2 extends keyof ED>(childNode: ListNode<ED, keyof ED, Cxt, AD>): ED[T2]['Selection']['filter'] {
|
||||
for (const key in this.children) {
|
||||
if (childNode === this.children[key]) {
|
||||
const rel = this.judgeRelation(key);
|
||||
const sliceIdx = key.indexOf(':');
|
||||
const key2 = sliceIdx > 0 ? key.slice(0, sliceIdx) : key;
|
||||
const rel = this.judgeRelation(key2);
|
||||
assert(rel instanceof Array);
|
||||
if (rel[1]) {
|
||||
// 基于普通外键的一对多
|
||||
|
|
@ -1174,7 +1217,6 @@ export class RunningTree<
|
|||
sorters,
|
||||
pagination
|
||||
);
|
||||
node.refresh();
|
||||
} else {
|
||||
node = new SingleNode<ED, T, Cxt, AD>(
|
||||
entity,
|
||||
|
|
@ -1184,9 +1226,6 @@ export class RunningTree<
|
|||
projectionShape,
|
||||
parentNode
|
||||
);
|
||||
if (id) {
|
||||
node.setId(id);
|
||||
}
|
||||
}
|
||||
if (parentNode) {
|
||||
parentNode.addChild(path, node as any);
|
||||
|
|
@ -1194,6 +1233,12 @@ export class RunningTree<
|
|||
assert(!parent && !this.root[path]);
|
||||
this.root[path] = node;
|
||||
}
|
||||
if (isList) {
|
||||
node.refresh();
|
||||
}
|
||||
else if (id) {
|
||||
(<SingleNode<ED, T, Cxt, AD>>node).setId(id);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import { BasicFeatures } from './features';
|
|||
import { ActionDictOfEntityDict } from 'oak-domain/lib/types/Action';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { ExceptionHandler, ExceptionRouters } from './types/ExceptionRoute';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page';
|
||||
import { createComponent, createPage } from './page.mp';
|
||||
import { OakComponentOption } from './types/Page2';
|
||||
import { createComponent } from './page.mp';
|
||||
import { initialize as initDev } from './initialize-dev';
|
||||
import { getI18next, I18nOptions } from './platforms/wechatMp/i18n';
|
||||
|
||||
|
|
@ -73,6 +73,7 @@ export function initialize<
|
|||
Object.assign(global, {
|
||||
OakComponent: <
|
||||
T extends keyof ED,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
|
|
@ -85,6 +86,7 @@ export function initialize<
|
|||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import { BasicFeatures } from './features';
|
|||
import { ActionDictOfEntityDict } from 'oak-domain/lib/types/Action';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { ExceptionHandler, ExceptionRouters } from './types/ExceptionRoute';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page';
|
||||
import { createComponent, createPage } from './page.mp';
|
||||
import { OakComponentOption } from './types/Page2';
|
||||
import { createComponent } from './page.mp';
|
||||
import { initialize as initProd } from './initialize-prod';
|
||||
import { getI18next, I18nOptions } from './platforms/wechatMp/i18n';
|
||||
|
||||
|
|
@ -60,44 +60,9 @@ export function initialize<
|
|||
const i18n = getI18next(i18nOptions);
|
||||
|
||||
Object.assign(global, {
|
||||
OakPage: <
|
||||
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: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>
|
||||
) =>
|
||||
createPage<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>(options, features, exceptionRouterDict),
|
||||
OakComponent: <
|
||||
T extends keyof ED,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
|
|
@ -110,6 +75,7 @@ export function initialize<
|
|||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import { BasicFeatures } from './features';
|
|||
import { ActionDictOfEntityDict } from 'oak-domain/lib/types/Action';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { ExceptionHandler, ExceptionRouters } from './types/ExceptionRoute';
|
||||
import { OakComponentOption, OakPageOption } from './types/Page';
|
||||
import { createComponent, createPage } from './page.web';
|
||||
import { OakComponentOption } from './types/Page2';
|
||||
import { createComponent } from './page.web2';
|
||||
import { initialize as initProd } from './initialize-prod';
|
||||
import { getI18next, I18nOptions } from './platforms/web/i18n';
|
||||
|
||||
|
|
@ -61,46 +61,11 @@ export function initialize<
|
|||
const i18n = getI18next(i18nOptions);
|
||||
|
||||
Object.assign(global, {
|
||||
OakPage: <
|
||||
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: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>
|
||||
) =>
|
||||
createPage<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>(options, features, exceptionRouterDict),
|
||||
OakComponent: <
|
||||
T extends keyof ED,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
|
|
@ -111,6 +76,7 @@ export function initialize<
|
|||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
|
|
@ -124,6 +90,7 @@ export function initialize<
|
|||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
|
|
|
|||
|
|
@ -1,950 +0,0 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import {
|
||||
Aspect,
|
||||
Context,
|
||||
DeduceSorterItem,
|
||||
EntityDict,
|
||||
OakException,
|
||||
OakInputIllegalException,
|
||||
} from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature, subscribe } from './types/Feature';
|
||||
import { NamedFilterItem, NamedSorterItem } from './types/NamedCondition';
|
||||
import {
|
||||
OakCommonComponentMethods,
|
||||
OakComponentData,
|
||||
OakComponentOption,
|
||||
OakComponentProperties,
|
||||
OakHiddenComponentMethods,
|
||||
OakListComponentMethods,
|
||||
OakComponentOnlyMethods,
|
||||
OakPageMethods,
|
||||
OakPageOption,
|
||||
} from './types/Page';
|
||||
|
||||
export type ComponentProps<
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption
|
||||
> = WechatMiniprogram.Component.PropertyOptionToData<
|
||||
OakComponentProperties & TProperty
|
||||
>;
|
||||
|
||||
export type ComponentData<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
TData extends WechatMiniprogram.Component.DataOption
|
||||
> = TData & FormedData & OakComponentData<ED, T>;
|
||||
|
||||
export type ComponentThisType<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption,
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption,
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption
|
||||
> = ThisType<
|
||||
{
|
||||
state: ComponentData<ED, T, FormedData, TData>;
|
||||
props: ComponentProps<TProperty>;
|
||||
setState: (data: any, callback?: () => void) => Promise<void>;
|
||||
triggerEvent: <DetailType = any>(
|
||||
name: string,
|
||||
detail?: DetailType,
|
||||
options?: WechatMiniprogram.Component.TriggerEventOption
|
||||
) => void;
|
||||
} & TMethod &
|
||||
OakCommonComponentMethods<ED, T> &
|
||||
OakHiddenComponentMethods &
|
||||
(IsList extends true ? OakListComponentMethods<ED, T> : {})
|
||||
>;
|
||||
|
||||
export function makeHiddenComponentMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption,
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption,
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption
|
||||
>(): OakHiddenComponentMethods &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
subscribe() {
|
||||
if (!this.subscribed) {
|
||||
this.subscribed = subscribe(() => this.reRender());
|
||||
}
|
||||
},
|
||||
|
||||
unsubscribe() {
|
||||
if (this.subscribed) {
|
||||
this.subscribed();
|
||||
this.subscribed = undefined;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function makeCommonComponentMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
exceptionRouterDict: Record<string, ExceptionHandler>,
|
||||
formData: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>['formData']
|
||||
): Omit<
|
||||
OakCommonComponentMethods<ED, T>,
|
||||
'navigateTo' | 'navigateBack' | 'resolveInput' | 'redirectTo' | 't'
|
||||
> &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
sub(type: string, callback: Function) {
|
||||
features.eventBus.sub(type, callback);
|
||||
},
|
||||
|
||||
unsub(type: string, callback: Function) {
|
||||
features.eventBus.unsub(type, callback);
|
||||
},
|
||||
|
||||
pub(type: string, options?: any) {
|
||||
features.eventBus.pub(type, options);
|
||||
},
|
||||
|
||||
unsubAll(type: string) {
|
||||
features.eventBus.unsubAll(type);
|
||||
},
|
||||
|
||||
save(key, item) {
|
||||
features.localStorage.save(key, item);
|
||||
},
|
||||
|
||||
load(key) {
|
||||
return features.localStorage.load(key);
|
||||
},
|
||||
|
||||
clear() {
|
||||
features.localStorage.clear();
|
||||
},
|
||||
|
||||
setNotification(data) {
|
||||
features.notification.setNotification(data);
|
||||
},
|
||||
|
||||
consumeNotification() {
|
||||
return features.notification.consumeNotification();
|
||||
},
|
||||
|
||||
setMessage(data) {
|
||||
features.message.setMessage(data);
|
||||
},
|
||||
|
||||
consumeMessage() {
|
||||
return features.message.consumeMessage();
|
||||
},
|
||||
|
||||
async reRender(extra) {
|
||||
if (this.state.oakEntity && this.state.oakFullpath) {
|
||||
const rows = features.runningTree.getFreshValue(
|
||||
this.state.oakFullpath
|
||||
);
|
||||
|
||||
const dirty = features.runningTree.isDirty(
|
||||
this.state.oakFullpath
|
||||
);
|
||||
|
||||
const oakLegalActions = [];
|
||||
if (this.state.newOakActions) {
|
||||
for (const action of this.state.newOakActions) {
|
||||
try {
|
||||
await features.runningTree.testAction(
|
||||
this.state.oakFullpath,
|
||||
action
|
||||
);
|
||||
oakLegalActions.push(action);
|
||||
} catch (e) {
|
||||
if (e instanceof OakInputIllegalException) {
|
||||
oakLegalActions.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const data: Record<string, any> = formData
|
||||
? await formData.call(this, {
|
||||
data: rows as any,
|
||||
features,
|
||||
props: this.props,
|
||||
legalActions: oakLegalActions,
|
||||
})
|
||||
: {};
|
||||
for (const k in data) {
|
||||
if (data[k] === undefined) {
|
||||
Object.assign(data, {
|
||||
[k]: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
Object.assign(data, { oakDirty: dirty });
|
||||
|
||||
if (extra) {
|
||||
Object.assign(data, extra);
|
||||
}
|
||||
|
||||
Object.assign(data, {
|
||||
oakLegalActions,
|
||||
});
|
||||
this.setState(data);
|
||||
} else {
|
||||
/**
|
||||
* 这里的data属性为undefined,但声明不太好写,很难精准的判断这种情况
|
||||
* 即使oakpage的entity属性为空也不行,有可能动态传入
|
||||
*/
|
||||
const data: Record<string, any> = formData
|
||||
? await formData.call(this, {
|
||||
features,
|
||||
props: this.props,
|
||||
} as any)
|
||||
: {};
|
||||
if (extra) {
|
||||
Object.assign(data, extra);
|
||||
}
|
||||
this.setState(data);
|
||||
}
|
||||
},
|
||||
|
||||
callPicker(attr: string, params: Record<string, any>) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
|
||||
const relation = features.cache.judgeRelation(
|
||||
this.state.oakEntity,
|
||||
attr
|
||||
);
|
||||
let subEntity: string;
|
||||
if (relation === 2) {
|
||||
subEntity = attr;
|
||||
} else {
|
||||
assert(typeof relation === 'string');
|
||||
subEntity = relation;
|
||||
}
|
||||
let url = `/pickers/${subEntity}?oakIsPicker=true&oakParentEntity=${this.state.oakEntity}&oakParent=${this.state.oakFullpath}&oakPath=${attr}`;
|
||||
for (const k in params) {
|
||||
url += `&${k}=${JSON.stringify(params[k])}`;
|
||||
}
|
||||
this.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
|
||||
async setForeignKey(id: string, goBackDelta: number = -1) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
const { oakIsPicker, oakParent, oakPath } = this.state;
|
||||
assert(oakIsPicker);
|
||||
await features.runningTree.setForeignKey(oakParent, oakPath, id);
|
||||
|
||||
if (goBackDelta !== 0) {
|
||||
this.navigateBack({
|
||||
delta: goBackDelta,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async addForeignKeys(ids: string[], goBackDelta: number = -1) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
const { oakIsPicker, oakParent, oakPath } = this.state;
|
||||
assert(oakIsPicker);
|
||||
await features.runningTree.addForeignKeys(oakParent, oakPath, ids);
|
||||
|
||||
if (goBackDelta !== 0) {
|
||||
this.navigateBack({
|
||||
delta: goBackDelta,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async setUniqueForeignKeys(ids: string[], goBackDelta: number = -1) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
const { oakIsPicker, oakParent, oakPath } = this.state;
|
||||
assert(oakIsPicker);
|
||||
await features.runningTree.setUniqueForeignKeys(oakParent, oakPath, ids);
|
||||
|
||||
if (goBackDelta !== 0) {
|
||||
this.navigateBack({
|
||||
delta: goBackDelta,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
async toggleNode(
|
||||
nodeData: Record<string, any>,
|
||||
checked: boolean,
|
||||
path?: string
|
||||
) {
|
||||
const fullpath = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
await features.runningTree.toggleNode(fullpath, nodeData, checked);
|
||||
},
|
||||
|
||||
async execute(action, legalExceptions, path) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
oakExecuting: true,
|
||||
oakFocused: {},
|
||||
});
|
||||
try {
|
||||
const fullpath = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
const result = await features.runningTree.execute(
|
||||
fullpath,
|
||||
action
|
||||
);
|
||||
this.setState({ oakExecuting: false });
|
||||
this.setMessage({
|
||||
type: 'success',
|
||||
content: '操作成功',
|
||||
});
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof OakException) {
|
||||
if (err instanceof OakInputIllegalException) {
|
||||
const attr = err.getAttributes()[0];
|
||||
this.setState({
|
||||
oakFocused: {
|
||||
[attr]: true,
|
||||
},
|
||||
oakExecuting: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'warning',
|
||||
content: err.message,
|
||||
});
|
||||
} else {
|
||||
const { name } = err.constructor;
|
||||
const handler = exceptionRouterDict[name];
|
||||
if (legalExceptions && legalExceptions.includes(name)) {
|
||||
// 如果调用时就知道有异常,直接抛出
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
throw err;
|
||||
} else if (handler) {
|
||||
const {
|
||||
hidden,
|
||||
level,
|
||||
handler: fn,
|
||||
router,
|
||||
disableNamespace,
|
||||
} = handler;
|
||||
if (!hidden) {
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: level || 'warning',
|
||||
content: err.message,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
}
|
||||
if (fn) {
|
||||
fn(err);
|
||||
return;
|
||||
} else if (router) {
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
this.navigateTo(
|
||||
{
|
||||
url: router,
|
||||
},
|
||||
{
|
||||
exception: err.toString(),
|
||||
},
|
||||
disableNamespace
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'warning',
|
||||
content: err.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setState({
|
||||
oakExecuting: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'warning',
|
||||
content: (err as Error).message,
|
||||
});
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
|
||||
resetUpdateData() {
|
||||
return features.runningTree.resetUpdateData(this.state.oakFullpath);
|
||||
},
|
||||
|
||||
async setAction(action, path) {
|
||||
const fullpath = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
return features.runningTree.setAction(fullpath, action);
|
||||
},
|
||||
|
||||
async setUpdateData(attr, value) {
|
||||
if (this.state.oakExecuting) {
|
||||
return;
|
||||
}
|
||||
return features.runningTree.setUpdateData(
|
||||
this.state.oakFullpath,
|
||||
attr,
|
||||
value
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function makeComponentOnlyMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
formData: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>['formData'],
|
||||
entity: T | undefined,
|
||||
actions: ED[T]['Action'][] | undefined,
|
||||
): OakComponentOnlyMethods &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
onPropsChanged(params) {
|
||||
const path2 = params.hasOwnProperty('path')
|
||||
? params.path!
|
||||
: this.props.oakPath;
|
||||
const parent2 = params.hasOwnProperty('parent')
|
||||
? params.parent!
|
||||
: this.props.oakParent;
|
||||
const oakFullpath2 = `${parent2 || ''}${
|
||||
parent2 && path2 ? '.' : ''
|
||||
}${path2 || ''}`;
|
||||
|
||||
if (oakFullpath2) {
|
||||
if (oakFullpath2 !== this.state.oakFullpath) {
|
||||
this.setState({
|
||||
oakFullpath: oakFullpath2,
|
||||
oakEntity: entity as string,
|
||||
});
|
||||
typeof formData === 'function' && this.reRender();
|
||||
}
|
||||
}
|
||||
},
|
||||
registerReRender() {
|
||||
const { oakPath, oakParent } = this.props;
|
||||
if (oakParent || oakPath) {
|
||||
const oakFullpath = `${oakParent || ''}${
|
||||
oakParent && oakPath ? '.' : ''
|
||||
}${oakPath || ''}`;
|
||||
this.setState(
|
||||
{
|
||||
oakFullpath,
|
||||
oakEntity: entity as any,
|
||||
},
|
||||
() => {
|
||||
typeof formData === 'function' &&
|
||||
this.reRender.call(this);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
typeof formData === 'function' && this.reRender.call(this);
|
||||
}
|
||||
},
|
||||
setOakActions() {
|
||||
const { oakActions } = this.props;
|
||||
this.setState({
|
||||
newOakActions:
|
||||
oakActions && JSON.parse(oakActions).length > 0
|
||||
? JSON.parse(oakActions)
|
||||
: actions || [],
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function makeListComponentMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD
|
||||
): OakListComponentMethods<ED, T> &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
async pushNode(path, options) {
|
||||
const path2 = path
|
||||
? `${this.state.oakFullpath}.${path}`
|
||||
: this.state.oakFullpath;
|
||||
await features.runningTree.pushNode(path2, options || {});
|
||||
},
|
||||
|
||||
async removeNode(parent, path) {
|
||||
const path2 = parent
|
||||
? `${this.state.oakFullpath}.${parent}`
|
||||
: this.state.oakFullpath;
|
||||
await features.runningTree.removeNode(path2, path);
|
||||
},
|
||||
|
||||
async getFilters() {
|
||||
if (this.state.oakFullpath) {
|
||||
const namedFilters = features.runningTree.getNamedFilters(
|
||||
this.state.oakFullpath
|
||||
);
|
||||
const filters = await Promise.all(
|
||||
namedFilters.map(({ filter }) => {
|
||||
if (typeof filter === 'function') {
|
||||
return filter();
|
||||
}
|
||||
return filter;
|
||||
})
|
||||
);
|
||||
return filters;
|
||||
}
|
||||
},
|
||||
|
||||
async getFilterByName(name) {
|
||||
if (this.state.oakFullpath) {
|
||||
const filter = features.runningTree.getNamedFilterByName(
|
||||
this.state.oakFullpath,
|
||||
name
|
||||
);
|
||||
if (filter?.filter) {
|
||||
if (typeof filter.filter === 'function') {
|
||||
return filter.filter();
|
||||
}
|
||||
return filter.filter;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async addNamedFilter(namedFilter, refresh = false) {
|
||||
await features.runningTree.addNamedFilter(
|
||||
this.state.oakFullpath,
|
||||
namedFilter,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async removeNamedFilter(namedFilter, refresh = false) {
|
||||
await features.runningTree.removeNamedFilter(
|
||||
this.state.oakFullpath,
|
||||
namedFilter,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async removeNamedFilterByName(name, refresh = false) {
|
||||
await features.runningTree.removeNamedFilterByName(
|
||||
this.state.oakFullpath,
|
||||
name,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async setNamedSorters(namedSorters) {
|
||||
await features.runningTree.setNamedSorters(
|
||||
this.state.oakFullpath,
|
||||
namedSorters
|
||||
);
|
||||
},
|
||||
|
||||
async getSorters() {
|
||||
if (this.state.oakFullpath) {
|
||||
const namedSorters = features.runningTree.getNamedSorters(
|
||||
this.state.oakFullpath
|
||||
);
|
||||
const sorters = (
|
||||
await Promise.all(
|
||||
namedSorters.map(({ sorter }) => {
|
||||
if (typeof sorter === 'function') {
|
||||
return sorter();
|
||||
}
|
||||
return sorter;
|
||||
})
|
||||
)
|
||||
).filter((ele) => !!ele) as DeduceSorterItem<ED[T]['Schema']>[];
|
||||
return sorters;
|
||||
}
|
||||
},
|
||||
|
||||
async getSorterByName(name) {
|
||||
if (this.state.oakFullpath) {
|
||||
const sorter = features.runningTree.getNamedSorterByName(
|
||||
this.state.oakFullpath,
|
||||
name
|
||||
);
|
||||
if (sorter?.sorter) {
|
||||
if (typeof sorter.sorter === 'function') {
|
||||
return sorter.sorter();
|
||||
}
|
||||
return sorter.sorter;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async addNamedSorter(namedSorter, refresh = false) {
|
||||
await features.runningTree.addNamedSorter(
|
||||
this.state.oakFullpath,
|
||||
namedSorter,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async removeNamedSorter(namedSorter, refresh = false) {
|
||||
await features.runningTree.removeNamedSorter(
|
||||
this.state.oakFullpath,
|
||||
namedSorter,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async removeNamedSorterByName(name, refresh = false) {
|
||||
await features.runningTree.removeNamedSorterByName(
|
||||
this.state.oakFullpath,
|
||||
name,
|
||||
refresh
|
||||
);
|
||||
},
|
||||
|
||||
async setFilters(filters) {
|
||||
await features.runningTree.setNamedFilters(
|
||||
this.state.oakFullpath,
|
||||
filters
|
||||
);
|
||||
},
|
||||
|
||||
getPagination() {
|
||||
if (this.state.oakFullpath) {
|
||||
return features.runningTree.getPagination(this.state.oakFullpath);
|
||||
}
|
||||
},
|
||||
|
||||
async setPageSize(pageSize: number, refresh = true) {
|
||||
features.runningTree.setPageSize(
|
||||
this.state.oakFullpath,
|
||||
pageSize,
|
||||
);
|
||||
if (refresh) {
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
|
||||
async setCurrentPage(currentPage: number) {
|
||||
assert(currentPage !== 0);
|
||||
|
||||
if (this.state.oakEntity && this.state.oakFullpath) {
|
||||
this.setState({
|
||||
oakLoading: true,
|
||||
});
|
||||
try {
|
||||
await features.runningTree.setCurrentPage(
|
||||
this.state.oakFullpath,
|
||||
currentPage
|
||||
);
|
||||
this.setState({
|
||||
oakLoading: false,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
oakLoading: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: (err as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function makePageMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
options: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>
|
||||
): OakPageMethods &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
async refresh() {
|
||||
if (this.state.oakEntity && this.state.oakFullpath) {
|
||||
this.setState({
|
||||
oakLoading: true,
|
||||
});
|
||||
try {
|
||||
await features.runningTree.refresh(this.state.oakFullpath);
|
||||
this.setState({
|
||||
oakLoading: false,
|
||||
});
|
||||
// this.setMessage({
|
||||
// type: 'success',
|
||||
// content: '访问成功',
|
||||
// })
|
||||
} catch (err) {
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: (err as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async onPullDownRefresh() {
|
||||
await this.refresh();
|
||||
},
|
||||
|
||||
async loadMore() {
|
||||
if (
|
||||
this.state.oakEntity &&
|
||||
this.state.oakFullpath &&
|
||||
options.isList
|
||||
) {
|
||||
this.setState({
|
||||
oakMoreLoading: true,
|
||||
});
|
||||
try {
|
||||
await features.runningTree.loadMore(this.state.oakFullpath);
|
||||
this.setState({
|
||||
oakMoreLoading: false,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
oakMoreLoading: false,
|
||||
});
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: (err as Error).message,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async onReachBottom() {
|
||||
await this.loadMore();
|
||||
},
|
||||
|
||||
async onLoad(pageOption) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const {
|
||||
oakId,
|
||||
oakEntity,
|
||||
oakPath,
|
||||
oakProjection,
|
||||
oakParent,
|
||||
oakSorters,
|
||||
oakFilters,
|
||||
oakIsPicker,
|
||||
oakFrom,
|
||||
oakActions,
|
||||
...props
|
||||
} = this.props;
|
||||
if (oakEntity || options.entity) {
|
||||
assert(!(options.isList && oakId));
|
||||
const filters: NamedFilterItem<ED, T>[] = [];
|
||||
if (oakFilters?.length > 0) {
|
||||
// 这里在跳页面的时候用this.navigate应该可以限制传过来的filter的格式
|
||||
const oakFilters2 = JSON.parse(oakFilters);
|
||||
filters.push(...oakFilters2);
|
||||
} else if (options.filters) {
|
||||
for (const ele of options.filters) {
|
||||
const { filter, '#name': name } = ele;
|
||||
filters.push({
|
||||
filter:
|
||||
typeof filter === 'function'
|
||||
? () =>
|
||||
filter({
|
||||
features,
|
||||
props: this.props,
|
||||
onLoadOptions: pageOption,
|
||||
})
|
||||
: filter,
|
||||
['#name']: name,
|
||||
});
|
||||
}
|
||||
}
|
||||
let proj = oakProjection && JSON.parse(oakProjection);
|
||||
if (!proj && options.projection) {
|
||||
const { projection } = options;
|
||||
proj =
|
||||
typeof projection === 'function'
|
||||
? () =>
|
||||
projection({
|
||||
features,
|
||||
props: this.props,
|
||||
onLoadOptions: pageOption,
|
||||
})
|
||||
: projection;
|
||||
}
|
||||
let sorters: NamedSorterItem<ED, T>[] = [];
|
||||
if (oakSorters?.length > 0) {
|
||||
// 这里在跳页面的时候用this.navigate应该可以限制传过来的sorter的格式
|
||||
const oakSorters2 = JSON.parse(oakSorters);
|
||||
sorters.push(...oakSorters2);
|
||||
} else if (options.sorters) {
|
||||
for (const ele of options.sorters) {
|
||||
const { sorter, '#name': name } = ele;
|
||||
sorters.push({
|
||||
sorter:
|
||||
typeof sorter === 'function'
|
||||
? () =>
|
||||
sorter({
|
||||
features,
|
||||
props: this.props,
|
||||
onLoadOptions: pageOption,
|
||||
})
|
||||
: sorter,
|
||||
['#name']: name,
|
||||
});
|
||||
}
|
||||
}
|
||||
const oakPath2 = oakPath || options.path;
|
||||
assert(
|
||||
oakPath2,
|
||||
'没有正确的path信息,请检查是否配置正确'
|
||||
);
|
||||
const path2 = oakParent
|
||||
? `${oakParent}:${oakPath2}`
|
||||
: oakPath2;
|
||||
const node = await features.runningTree.createNode({
|
||||
path: path2,
|
||||
entity: (oakEntity || options.entity) as T,
|
||||
isList: options.isList,
|
||||
isPicker: oakIsPicker,
|
||||
projection: proj,
|
||||
pagination: options.pagination,
|
||||
filters,
|
||||
sorters,
|
||||
id: oakId,
|
||||
});
|
||||
await this.setState(
|
||||
{
|
||||
oakEntity: node.getEntity(),
|
||||
oakFullpath: path2,
|
||||
oakFrom,
|
||||
},
|
||||
async () => {
|
||||
this.setOakActions();
|
||||
this.refresh();
|
||||
options.methods?.onLoad &&
|
||||
(await options.methods.onLoad.call(
|
||||
this,
|
||||
pageOption
|
||||
));
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
options.methods?.onLoad &&
|
||||
(await options.methods.onLoad.call(
|
||||
this,
|
||||
pageOption
|
||||
));
|
||||
|
||||
resolve();
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ export async function onPathSet<
|
|||
oakFullpath: oakPath2,
|
||||
oakIsReady: true,
|
||||
});
|
||||
await this.refresh();
|
||||
// await this.refresh();
|
||||
}
|
||||
|
||||
export async function reRender<
|
||||
|
|
@ -285,7 +285,7 @@ export function callPicker<
|
|||
assert(typeof relation === 'string');
|
||||
subEntity = relation;
|
||||
}
|
||||
let url = `/pickers/${subEntity}?oakIsPicker=true&oakParentEntity=${this.state.oakEntity}&oakParent=${this.state.oakFullpath}&oakPath=${attr}`;
|
||||
let url = `/pickers/${subEntity}?oakIsPicker=true&oakParentEntity=${this.state.oakEntity as string}&oakParent=${this.state.oakFullpath}&oakPath=${attr}`;
|
||||
for (const k in params) {
|
||||
url += `&${k}=${JSON.stringify(params[k])}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
OakComponentOption,
|
||||
OakPageMethods,
|
||||
OakPageOption,
|
||||
} from './types/Page';
|
||||
} from './types/Page2';
|
||||
import {
|
||||
ComponentThisType,
|
||||
makeHiddenComponentMethods,
|
||||
|
|
@ -20,7 +20,7 @@ import {
|
|||
makeComponentOnlyMethods,
|
||||
makeCommonComponentMethods as makeCommon,
|
||||
makePageMethods as makePage,
|
||||
} from './page.common';
|
||||
} from './page.common2';
|
||||
import {
|
||||
getI18nInstanceWechatMp,
|
||||
CURRENT_LOCALE_KEY,
|
||||
|
|
|
|||
678
src/page.web.tsx
678
src/page.web.tsx
|
|
@ -1,678 +0,0 @@
|
|||
import React from 'react';
|
||||
import { withRouter, PullToRefresh } from './platforms/web';
|
||||
import { get } from 'oak-domain/lib/utils/lodash';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { BasicFeatures } from './features';
|
||||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { Feature } from './types/Feature';
|
||||
import {
|
||||
MiniprogramStyleMethods,
|
||||
OakCommonComponentMethods,
|
||||
OakComponentData,
|
||||
OakComponentOption,
|
||||
OakPageData,
|
||||
OakPageMethods,
|
||||
OakPageOption,
|
||||
OakPageProperties,
|
||||
} from './types/Page';
|
||||
import {
|
||||
ComponentThisType,
|
||||
makeHiddenComponentMethods,
|
||||
makeListComponentMethods,
|
||||
makeComponentOnlyMethods,
|
||||
makeCommonComponentMethods as makeCommon,
|
||||
makePageMethods as makePage,
|
||||
ComponentData,
|
||||
ComponentProps,
|
||||
} from './page.common';
|
||||
|
||||
function makeCommonComponentMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
exceptionRouterDict: Record<string, ExceptionHandler>,
|
||||
formData: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>['formData']
|
||||
): OakCommonComponentMethods<ED, T> &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
return {
|
||||
t(key: string, params?: object) {
|
||||
// common: {
|
||||
// GREETING: 'Hello {{name}}, nice to see you.',
|
||||
// },
|
||||
// t('common:GREETING', {name: "John Doe" })
|
||||
return this.props.t(key, params);
|
||||
},
|
||||
resolveInput(input: React.BaseSyntheticEvent, keys) {
|
||||
const { currentTarget, target } = input;
|
||||
const { value } = Object.assign({}, currentTarget, target);
|
||||
const { dataset } = currentTarget;
|
||||
const result = {
|
||||
dataset,
|
||||
value,
|
||||
};
|
||||
if (keys) {
|
||||
keys.forEach((k) =>
|
||||
Object.assign(result, {
|
||||
[k]: target[k],
|
||||
})
|
||||
);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
navigateBack(option) {
|
||||
const { delta } = option || {};
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
this.props.navigate(delta || -1);
|
||||
resolve(undefined);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
navigateTo(options, state, disableNamespace) {
|
||||
const { url, events, fail, complete, success, ...rest } = options;
|
||||
let url2 = url.includes('?')
|
||||
? url.concat(
|
||||
this.state.oakFullpath
|
||||
? `&oakFrom=${this.state.oakFullpath}`
|
||||
: ''
|
||||
)
|
||||
: url.concat(
|
||||
this.state.oakFullpath ? `?oakFrom=${this.state.oakFullpath}` : ''
|
||||
);
|
||||
|
||||
for (const param in rest) {
|
||||
const param2 = param as unknown as keyof typeof rest;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += `${url2.includes('?') ? '&' : '?'}${param}=${
|
||||
typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2])
|
||||
}`;
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: false, state });
|
||||
},
|
||||
redirectTo(options, state, disableNamespace) {
|
||||
const { url, events, fail, complete, success, ...rest } = options;
|
||||
let url2 = url.includes('?')
|
||||
? url.concat(
|
||||
this.state.oakFullpath
|
||||
? `&oakFrom=${this.state.oakFullpath}`
|
||||
: ''
|
||||
)
|
||||
: url.concat(
|
||||
this.state.oakFullpath
|
||||
? `?oakFrom=${this.state.oakFullpath}`
|
||||
: ''
|
||||
);
|
||||
|
||||
for (const param in rest) {
|
||||
const param2 = param as unknown as keyof typeof rest;
|
||||
if (rest[param2] !== undefined) {
|
||||
url2 += `${url2.includes('?') ? '&' : '?'}${param}=${
|
||||
typeof rest[param2] === 'string'
|
||||
? rest[param2]
|
||||
: JSON.stringify(rest[param2])
|
||||
}`;
|
||||
}
|
||||
}
|
||||
// 路由传入namespace
|
||||
if (!disableNamespace && this.props.namespace) {
|
||||
url2 =
|
||||
(this.props.namespace.startsWith('/') ? '' : '/') +
|
||||
(this.props.namespace === '/' ? '' : this.props.namespace) +
|
||||
(url2.startsWith('/') ? '' : '/') +
|
||||
url2;
|
||||
}
|
||||
return this.props.navigate(url2, { replace: true, state });
|
||||
},
|
||||
|
||||
...makeCommon(features, exceptionRouterDict, formData),
|
||||
};
|
||||
}
|
||||
|
||||
function makePageMethods<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
FormedData extends WechatMiniprogram.Component.DataOption,
|
||||
Proj extends ED[T]['Selection']['data'],
|
||||
IsList extends boolean,
|
||||
TData extends WechatMiniprogram.Component.DataOption = {},
|
||||
TProperty extends WechatMiniprogram.Component.PropertyOption = {},
|
||||
TMethod extends WechatMiniprogram.Component.MethodOption = {}
|
||||
>(
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
options: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>
|
||||
): OakPageMethods &
|
||||
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
|
||||
const { onPullDownRefresh, ...rest } = makePage(features, options);
|
||||
return {
|
||||
async onPullDownRefresh() {
|
||||
await onPullDownRefresh.call(this);
|
||||
},
|
||||
...rest,
|
||||
};
|
||||
}
|
||||
|
||||
function translateObservers(
|
||||
observers?: Record<string, (...args: any[]) => any>
|
||||
): { fn: React.Component['componentDidUpdate'] } & ThisType<React.Component> {
|
||||
return {
|
||||
fn(prevProps, prevState) {
|
||||
const { state, props } = this;
|
||||
for (const obs in observers) {
|
||||
const keys = obs.split(',').map((ele) => ele.trim());
|
||||
let changed = false;
|
||||
for (const k of keys) {
|
||||
if (k.includes('*')) {
|
||||
throw new Error('web模式下带*的observer通配符暂不支持');
|
||||
}
|
||||
if (
|
||||
get(props, k) !== get(prevProps, k) ||
|
||||
get(state, k) !== get(prevState, k)
|
||||
) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const args = [];
|
||||
if (changed) {
|
||||
for (const k of keys) {
|
||||
args.push(
|
||||
get(props, k) === undefined
|
||||
? get(state, k)
|
||||
: get(props, k)
|
||||
);
|
||||
}
|
||||
observers[obs].apply(this, args);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function makeMiniprogramCompatibleFunctions(): MiniprogramStyleMethods &
|
||||
ThisType<React.Component> {
|
||||
return {
|
||||
triggerEvent(name, detail, option) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
animate(selector, frames, duration, timeline) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
clearAnimation(selector, option, callback) {
|
||||
throw new Error('method not implemented yet');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_REACH_BOTTOM_DISTANCE = 50;
|
||||
|
||||
export function createPage<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
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: OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>,
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
exceptionRouterDict: Record<string, ExceptionHandler>
|
||||
) {
|
||||
const { formData, isList, render, actions, entity } =
|
||||
options as OakPageOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
Proj,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
> & {
|
||||
render: () => React.ReactNode &
|
||||
ComponentThisType<
|
||||
ED,
|
||||
T,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>;
|
||||
};
|
||||
const hiddenMethods = makeHiddenComponentMethods();
|
||||
const commonMethods = makeCommonComponentMethods(
|
||||
features,
|
||||
exceptionRouterDict,
|
||||
formData
|
||||
);
|
||||
const listMethods = makeListComponentMethods(features);
|
||||
const onlyMethods = makeComponentOnlyMethods(formData, entity, actions);
|
||||
const { onLoad, onPullDownRefresh, onReachBottom, ...restPageMethods } =
|
||||
makePageMethods(features, options);
|
||||
|
||||
const { methods, lifetimes, pageLifetimes, data, observers } = options;
|
||||
|
||||
const { fn } = translateObservers(observers);
|
||||
class OakPageWrapper extends React.PureComponent<
|
||||
ComponentProps<TProperty>,
|
||||
ComponentData<ED, T, FormedData, TData>
|
||||
> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = (data || {}) as any;
|
||||
for (const m in commonMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: commonMethods[m as keyof typeof commonMethods]!.bind(
|
||||
this
|
||||
),
|
||||
});
|
||||
}
|
||||
for (const m in listMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: listMethods[m as keyof typeof listMethods]!.bind(this),
|
||||
});
|
||||
}
|
||||
for (const m in hiddenMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: hiddenMethods[m as keyof typeof hiddenMethods]!.bind(
|
||||
this
|
||||
),
|
||||
});
|
||||
}
|
||||
for (const m in onlyMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: onlyMethods[m as keyof typeof onlyMethods]!.bind(this),
|
||||
});
|
||||
}
|
||||
for (const m in restPageMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: restPageMethods[
|
||||
m as keyof typeof restPageMethods
|
||||
]!.bind(this),
|
||||
});
|
||||
}
|
||||
if (methods) {
|
||||
const { onPullDownRefresh, onReachBottom, ...restMethods } =
|
||||
methods;
|
||||
for (const m in restMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: restMethods[m as keyof typeof restMethods]!.bind(
|
||||
this
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
lifetimes?.created && lifetimes.created.call(this);
|
||||
}
|
||||
|
||||
features = features;
|
||||
isReachBottom = false;
|
||||
componentDidUpdate = fn;
|
||||
|
||||
scrollEvent = () => {
|
||||
this.checkReachBottom();
|
||||
};
|
||||
|
||||
registerPageScroll() {
|
||||
const { useBodyScroll = false } = this.props;
|
||||
if (useBodyScroll) {
|
||||
window.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
(this as any).lv && (this as any).lv.addEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterPageScroll() {
|
||||
const { useBodyScroll = false } = this.props;
|
||||
if (useBodyScroll) {
|
||||
window.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
else {
|
||||
(this as any).lv && (this as any).lv.removeEventListener('scroll', this.scrollEvent);
|
||||
}
|
||||
}
|
||||
|
||||
checkReachBottom() {
|
||||
const isCurrentReachBottom =
|
||||
document.body.scrollHeight -
|
||||
(window.innerHeight + window.scrollY) <=
|
||||
DEFAULT_REACH_BOTTOM_DISTANCE;
|
||||
|
||||
if (!this.isReachBottom && isCurrentReachBottom) {
|
||||
this.isReachBottom = true;
|
||||
// 执行触底事件
|
||||
if (methods?.onReachBottom) {
|
||||
methods.onReachBottom.call(this);
|
||||
return;
|
||||
}
|
||||
if (this.props.width === 'xs') {
|
||||
onReachBottom.call(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.isReachBottom = isCurrentReachBottom;
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.registerPageScroll();
|
||||
await onLoad.call(this, this.props);
|
||||
typeof formData === 'function' && hiddenMethods.subscribe.call(this);
|
||||
typeof formData === 'function' && commonMethods.reRender.call(this);
|
||||
methods?.onReady && methods.onReady.call(this);
|
||||
lifetimes?.attached && lifetimes.attached.call(this);
|
||||
lifetimes?.ready && lifetimes.ready.call(this);
|
||||
pageLifetimes?.show && pageLifetimes.show.call(this);
|
||||
}
|
||||
|
||||
async componentWillUnmount() {
|
||||
this.unregisterPageScroll();
|
||||
this.state.oakFullpath && features.runningTree.destroyNode(this.state.oakFullpath);
|
||||
typeof formData === 'function' && hiddenMethods.unsubscribe.call(this);
|
||||
methods?.onUnload && methods.onUnload.call(this);
|
||||
lifetimes?.detached && lifetimes.detached.call(this);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
const Render = render.call(this);
|
||||
const { oakLoading } = this.state;
|
||||
const { enablePullDownRefresh, useBodyScroll = false } = this.props;
|
||||
|
||||
if (enablePullDownRefresh && this.props.width === 'xs') {
|
||||
const child = React.cloneElement(
|
||||
<PullToRefresh
|
||||
onRefresh={() => {
|
||||
if (methods?.onPullDownRefresh) {
|
||||
methods.onPullDownRefresh.call(this);
|
||||
} else {
|
||||
onPullDownRefresh.call(this);
|
||||
}
|
||||
}}
|
||||
refreshing={oakLoading}
|
||||
distanceToRefresh={DEFAULT_REACH_BOTTOM_DISTANCE}
|
||||
indicator={{
|
||||
activate: commonMethods.t.call(
|
||||
this,
|
||||
'common:ptrActivate'
|
||||
),
|
||||
deactivate: commonMethods.t.call(
|
||||
this,
|
||||
'common:ptrDeactivate'
|
||||
),
|
||||
release: commonMethods.t.call(
|
||||
this,
|
||||
'common:ptrRelease'
|
||||
),
|
||||
finish: commonMethods.t.call(
|
||||
this,
|
||||
'common:ptrFinish'
|
||||
),
|
||||
}}
|
||||
/>,
|
||||
{
|
||||
getScrollContainer: () => useBodyScroll ? document.body : (this as any).lv,
|
||||
},
|
||||
Render
|
||||
);
|
||||
return useBodyScroll ? (
|
||||
child
|
||||
) : (
|
||||
<div
|
||||
ref={(el) => ((this as any).lv = el)}
|
||||
style={{ height: '100%', overflow: 'auto' }}
|
||||
>
|
||||
{child}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return Render;
|
||||
}
|
||||
}
|
||||
|
||||
// 可能有问题,by Xc
|
||||
Object.assign(OakPageWrapper, makeMiniprogramCompatibleFunctions());
|
||||
return withRouter(OakPageWrapper, false, options.path);
|
||||
}
|
||||
|
||||
export function createComponent<
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends Context<ED>,
|
||||
AD extends Record<string, Aspect<ED, Cxt>>,
|
||||
FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>,
|
||||
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,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>,
|
||||
features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD,
|
||||
exceptionRouterDict: Record<string, ExceptionHandler>,
|
||||
) {
|
||||
const {
|
||||
formData,
|
||||
isList,
|
||||
entity,
|
||||
methods,
|
||||
lifetimes,
|
||||
pageLifetimes,
|
||||
data,
|
||||
properties,
|
||||
observers,
|
||||
actions,
|
||||
render,
|
||||
} = options as OakComponentOption<
|
||||
ED,
|
||||
T,
|
||||
Cxt,
|
||||
AD,
|
||||
FD,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
> & {
|
||||
render: () => React.ReactNode &
|
||||
ComponentThisType<
|
||||
ED,
|
||||
T,
|
||||
FormedData,
|
||||
IsList,
|
||||
TData,
|
||||
TProperty,
|
||||
TMethod
|
||||
>;
|
||||
};
|
||||
const hiddenMethods = makeHiddenComponentMethods();
|
||||
const commonMethods = makeCommonComponentMethods(
|
||||
features,
|
||||
exceptionRouterDict,
|
||||
formData
|
||||
);
|
||||
const listMethods = makeListComponentMethods(features);
|
||||
const onlyMethods = makeComponentOnlyMethods(formData, entity, actions);
|
||||
const { fn } = translateObservers(observers);
|
||||
class OakComponentWrapper extends React.PureComponent<
|
||||
ComponentProps<TProperty>,
|
||||
OakComponentData<ED, T>
|
||||
> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = (data || {}) as any;
|
||||
for (const m in commonMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: commonMethods[m as keyof typeof commonMethods]!.bind(
|
||||
this
|
||||
),
|
||||
});
|
||||
}
|
||||
for (const m in listMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: listMethods[m as keyof typeof listMethods]!.bind(this),
|
||||
});
|
||||
}
|
||||
for (const m in hiddenMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: hiddenMethods[m as keyof typeof hiddenMethods]!.bind(this),
|
||||
});
|
||||
}
|
||||
for (const m in onlyMethods) {
|
||||
Object.assign(this, {
|
||||
[m]: onlyMethods[m as keyof typeof onlyMethods]!.bind(this),
|
||||
});
|
||||
}
|
||||
if (methods) {
|
||||
for (const m in methods) {
|
||||
Object.assign(this, {
|
||||
[m]: methods[m as keyof typeof methods]!.bind(this),
|
||||
});
|
||||
}
|
||||
}
|
||||
lifetimes?.created && lifetimes.created.call(this);
|
||||
}
|
||||
|
||||
features = features;
|
||||
isReachBottom = false;
|
||||
|
||||
async componentDidMount() {
|
||||
typeof formData === 'function' && hiddenMethods.subscribe.call(this);
|
||||
(this as any).setOakActions();
|
||||
(this as any).registerReRender();
|
||||
lifetimes?.attached && lifetimes.attached.call(this);
|
||||
lifetimes?.ready && lifetimes.ready.call(this);
|
||||
pageLifetimes?.show && pageLifetimes.show.call(this);
|
||||
}
|
||||
|
||||
async componentWillUnmount() {
|
||||
typeof formData === 'function' && hiddenMethods.unsubscribe.call(this);
|
||||
lifetimes?.detached && lifetimes.detached.call(this);
|
||||
}
|
||||
|
||||
componentDidUpdate(
|
||||
prevProps: Readonly<ComponentProps<TProperty>>,
|
||||
prevState: Readonly<OakComponentData<ED, T>>
|
||||
) {
|
||||
if (
|
||||
this.props.oakPath &&
|
||||
prevProps.oakPath !== this.props.oakPath
|
||||
) {
|
||||
(this as any).onPropsChanged({
|
||||
path: this.props.oakPath,
|
||||
});
|
||||
}
|
||||
if (
|
||||
this.props.oakParent &&
|
||||
prevProps.oakParent !== this.props.oakParent
|
||||
) {
|
||||
(this as any).onPropsChanged({
|
||||
parent: this.props.oakParent,
|
||||
});
|
||||
}
|
||||
fn?.call(this, prevProps, prevState);
|
||||
}
|
||||
|
||||
render(): React.ReactNode {
|
||||
const Render = render.call(this);
|
||||
return Render;
|
||||
}
|
||||
|
||||
triggerEvent<DetailType = any>(
|
||||
name: string,
|
||||
detail?: DetailType,
|
||||
options?: WechatMiniprogram.Component.TriggerEventOption
|
||||
) {
|
||||
// 需要兼容
|
||||
}
|
||||
}
|
||||
|
||||
// 可能有问题,by Xc
|
||||
Object.assign(OakComponentWrapper, makeMiniprogramCompatibleFunctions());
|
||||
return withRouter(OakComponentWrapper, true);
|
||||
}
|
||||
|
|
@ -10,14 +10,9 @@ import { BasicFeatures } from './features';
|
|||
import { ExceptionHandler } from './types/ExceptionRoute';
|
||||
import { NamedFilterItem, NamedSorterItem } from './types/NamedCondition';
|
||||
import { Feature } from './types/Feature';
|
||||
import { CreateNodeOptions } from './features/runningTree';
|
||||
import {
|
||||
ComponentData,
|
||||
ComponentFullThisType,
|
||||
ComponentProps,
|
||||
MiniprogramStyleMethods,
|
||||
OakCommonComponentMethods,
|
||||
OakComponentData,
|
||||
OakComponentOption,
|
||||
OakNavigateToParameters,
|
||||
} from './types/Page2';
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ export function subscribe(callback: () => any) {
|
|||
const method = descriptor.value!;
|
||||
descriptor.value = async function (...params: any[]) {
|
||||
mActionStackDepth++;
|
||||
if (mActionStackDepth > 20) {
|
||||
console.error(`action[${method.name}]调用的层级超过了20,请检查是否存在无限递归`);
|
||||
}
|
||||
let result;
|
||||
try {
|
||||
result = await method.apply(this, params);
|
||||
|
|
|
|||
|
|
@ -289,10 +289,7 @@ export type OakCommonComponentMethods<
|
|||
export type OakListComponentMethods<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
|
||||
pushNode: (
|
||||
path?: string,
|
||||
options?: Pick<
|
||||
CreateNodeOptions<ED, keyof ED>,
|
||||
'updateData' | 'beforeExecute' | 'afterExecute'
|
||||
>
|
||||
options?: CreateNodeOptions<ED, keyof ED>
|
||||
) => Promise<void>;
|
||||
removeNode: (parent: string, path: string) => Promise<void>;
|
||||
setFilters: (filters: NamedFilterItem<ED, T>[]) => Promise<void>;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@
|
|||
],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/page.web.tsx",
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
|
|
|
|||
Loading…
Reference in New Issue