修正了refresh的判定逻辑
This commit is contained in:
parent
89a30cd291
commit
4ec9515086
|
|
@ -41,6 +41,7 @@ declare class UpdateLogManager<ED extends EntityDict & BaseEntityDict, T extends
|
|||
}
|
||||
declare abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feature {
|
||||
private zombie;
|
||||
protected stale?: boolean;
|
||||
/**
|
||||
* 当前有几个组件正在使用这个结点
|
||||
*/
|
||||
|
|
@ -68,6 +69,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feat
|
|||
isLoadingMore(): boolean;
|
||||
saveExtraData(key: string, data: any): void;
|
||||
loadExtraData(key: string): any;
|
||||
isStale(): boolean;
|
||||
abstract getParent(): Node<ED> | undefined;
|
||||
}
|
||||
declare abstract class EntityNode<ED extends EntityDict & BaseEntityDict, T extends keyof ED> extends Node<ED> {
|
||||
|
|
@ -107,7 +109,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
|
|||
}> | undefined;
|
||||
onCacheSync(records: OpRecord<ED>[]): void;
|
||||
destroy(): void;
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED>, path?: string, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], getTotal?: number, pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>);
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED>, path?: string, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], getTotal?: number, pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>, stale?: boolean);
|
||||
getPagination(): Pagination;
|
||||
setPagination(pagination: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>, dontRefresh?: true): void;
|
||||
addChild(path: string, node: SingleNode<ED, T>): void;
|
||||
|
|
@ -190,7 +192,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
[K: string]: SingleNode<ED, keyof ED> | ListNode<ED, keyof ED>;
|
||||
};
|
||||
private filters?;
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, path: string, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED> | ListNode<ED, T>, id?: string, filters?: NamedFilterItem<ED, T>[]);
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, path: string, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED> | ListNode<ED, T>, id?: string, filters?: NamedFilterItem<ED, T>[], stale?: boolean);
|
||||
getModiOperations(): Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
@ -243,7 +245,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
}
|
||||
declare class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<ED> {
|
||||
protected children: Record<string, SingleNode<ED, keyof ED> | ListNode<ED, keyof ED> | VirtualNode<ED>>;
|
||||
constructor(path?: string, parent?: VirtualNode<ED>);
|
||||
constructor(path?: string, parent?: VirtualNode<ED>, stale?: boolean);
|
||||
getModiOperations(): Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
@ -278,6 +280,7 @@ export type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends
|
|||
afterExecute?: (operations: ED[T]['Operation'][]) => Promise<void>;
|
||||
id?: string;
|
||||
zombie: boolean;
|
||||
stale?: boolean;
|
||||
};
|
||||
export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature {
|
||||
private logSerailNumber;
|
||||
|
|
@ -310,8 +313,9 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
|
|||
isLoading(path: string): boolean | undefined;
|
||||
isLoadingMore(path: string): boolean | undefined;
|
||||
isExecuting(path: string): boolean;
|
||||
private isListDescandent;
|
||||
private isListDescandentOrStaleBranch;
|
||||
private isInModiNextBranch;
|
||||
needNotRefresh(path: string): boolean;
|
||||
refresh(path: string, pageNumber?: number): Promise<void>;
|
||||
loadMore(path: string): Promise<void>;
|
||||
getPagination(path: string): Pagination;
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ class UpdateLogManager {
|
|||
}
|
||||
class Node extends Feature {
|
||||
zombie = false;
|
||||
stale;
|
||||
/**
|
||||
* 当前有几个组件正在使用这个结点
|
||||
*/
|
||||
|
|
@ -249,6 +250,9 @@ class Node extends Feature {
|
|||
loadExtraData(key) {
|
||||
return this.extraData[key];
|
||||
}
|
||||
isStale() {
|
||||
return !!this.isStale;
|
||||
}
|
||||
}
|
||||
class EntityNode extends Node {
|
||||
entity;
|
||||
|
|
@ -542,7 +546,7 @@ class ListNode extends EntityNode {
|
|||
this.children[k].destroy();
|
||||
}
|
||||
}
|
||||
constructor(entity, schema, cache, projection, parent, path, filters, sorters, getTotal, pagination) {
|
||||
constructor(entity, schema, cache, projection, parent, path, filters, sorters, getTotal, pagination, stale) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.filters = filters || [];
|
||||
this.sorters = sorters || [];
|
||||
|
|
@ -555,6 +559,7 @@ class ListNode extends EntityNode {
|
|||
total: 0,
|
||||
count: 0,
|
||||
} : { ...DEFAULT_PAGINATION };
|
||||
this.stale = stale;
|
||||
this.syncHandler = (records) => this.onCacheSync(records);
|
||||
this.cache.bindOnSync(this.syncHandler);
|
||||
if (parent) {
|
||||
|
|
@ -1053,11 +1058,12 @@ class SingleNode extends EntityNode {
|
|||
sr;
|
||||
children;
|
||||
filters;
|
||||
constructor(entity, schema, cache, path, projection, parent, id, filters) {
|
||||
constructor(entity, schema, cache, path, projection, parent, id, filters, stale) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.children = {};
|
||||
this.sr = {};
|
||||
this.filters = filters;
|
||||
this.stale = stale;
|
||||
// addChild有可能为本结点赋上id值,所以要先行
|
||||
if (parent) {
|
||||
assert(path);
|
||||
|
|
@ -1637,9 +1643,10 @@ class SingleNode extends EntityNode {
|
|||
}
|
||||
class VirtualNode extends Node {
|
||||
children;
|
||||
constructor(path, parent) {
|
||||
constructor(path, parent, stale) {
|
||||
super();
|
||||
this.children = {};
|
||||
this.stale = stale;
|
||||
if (parent) {
|
||||
parent.addChild(path, this);
|
||||
}
|
||||
|
|
@ -1793,7 +1800,7 @@ export class RunningTree extends Feature {
|
|||
this.logSerailNumber = START_LSN;
|
||||
}
|
||||
createNode(options, isPage) {
|
||||
const { entity, pagination, path: fullPath, filters, sorters, projection, isList, id, getTotal, zombie, } = options;
|
||||
const { entity, pagination, path: fullPath, filters, sorters, projection, isList, id, getTotal, zombie, stale, } = options;
|
||||
let node;
|
||||
const { parent, path } = analyzePath(fullPath);
|
||||
const parentNode = parent ? this.findNode(parent) : undefined;
|
||||
|
|
@ -1860,16 +1867,16 @@ export class RunningTree extends Feature {
|
|||
if (isList) {
|
||||
assert(!(parentNode instanceof ListNode));
|
||||
// assert(projection, `页面没有定义投影「${path}」`);
|
||||
node = new ListNode(entity, this.schema, this.cache, projection, parentNode, path, filters, sorters, getTotal, pagination);
|
||||
node = new ListNode(entity, this.schema, this.cache, projection, parentNode, path, filters, sorters, getTotal, pagination, stale);
|
||||
}
|
||||
else {
|
||||
node = new SingleNode(entity, this.schema, this.cache, path, projection, parentNode, // 过编译
|
||||
id, filters);
|
||||
id, filters, stale);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(!parentNode || parentNode instanceof VirtualNode);
|
||||
node = new VirtualNode(path, parentNode);
|
||||
node = new VirtualNode(path, parentNode, stale);
|
||||
}
|
||||
if (!parentNode) {
|
||||
assert(!parent && !this.root[path]);
|
||||
|
|
@ -2018,11 +2025,11 @@ export class RunningTree extends Feature {
|
|||
const node = this.findNode(path);
|
||||
return node ? node.isExecuting() : false;
|
||||
}
|
||||
isListDescandent(path) {
|
||||
isListDescandentOrStaleBranch(path) {
|
||||
const node = this.findNode(path);
|
||||
let parent = node?.getParent();
|
||||
while (parent) {
|
||||
if (parent instanceof ListNode) {
|
||||
if (parent instanceof ListNode || parent.isStale()) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
|
|
@ -2076,10 +2083,10 @@ export class RunningTree extends Feature {
|
|||
assert(false);
|
||||
return false;
|
||||
}
|
||||
needNotRefresh(path) {
|
||||
return this.isListDescandentOrStaleBranch(path) || this.isInModiNextBranch(path);
|
||||
}
|
||||
async refresh(path, pageNumber) {
|
||||
if (this.isInModiNextBranch(path) || this.isListDescandent(path)) {
|
||||
return;
|
||||
}
|
||||
const node = this.findNode(path);
|
||||
if (!node?.isLoading()) {
|
||||
if (node instanceof ListNode) {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { generateNewId } from 'oak-domain/lib/utils/uuid';
|
|||
import { compareRow, compareRows } from 'oak-domain/lib/utils/row';
|
||||
export function onPathSet(option, isPage) {
|
||||
const { props, state } = this;
|
||||
const { oakPath, oakId, oakFilters, oakZombie } = props;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal } = option;
|
||||
const { oakPath, oakId, oakFilters, oakZombie, oakStale } = props;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal, stale } = option;
|
||||
const { features } = this;
|
||||
assert(isPage || zombie === undefined, 'zombie只在页面级别声明');
|
||||
assert(isPage || path === undefined, 'path只在页面级别自动声明');
|
||||
|
|
@ -109,6 +109,7 @@ export function onPathSet(option, isPage) {
|
|||
// cascadeActions: cascadeActions && (() => cascadeActions.call(this)),
|
||||
getTotal: getTotal2,
|
||||
zombie: isPage ? !!zombie : !!oakZombie,
|
||||
stale: !!oakStale || !!stale,
|
||||
}, isPage);
|
||||
this.addFeatureSub('runningTree', (path2) => {
|
||||
// 父结点改变,子结点要重渲染
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ const oakBehavior = Behavior({
|
|||
this.oakOption.lifetimes?.ready &&
|
||||
this.oakOption.lifetimes?.ready.call(this);
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !this.oakOption.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
@ -788,7 +788,7 @@ export function createComponent(option, features) {
|
|||
return;
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
try {
|
||||
await this.refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ export function createComponent(option, features) {
|
|||
}
|
||||
try {
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
await this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
@ -704,7 +704,7 @@ export function createComponent(option, features) {
|
|||
lifetimes?.show && lifetimes.show.call(this);
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ type OakComponentProperties<ED extends EntityDict & BaseEntityDict, T extends ke
|
|||
oakParentEntity: string;
|
||||
oakDisablePulldownRefresh: boolean;
|
||||
oakZombie: boolean;
|
||||
oakStale: boolean;
|
||||
oakAutoUnmount: boolean;
|
||||
oakActions: string;
|
||||
oakCascadeActions: string;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ declare class UpdateLogManager<ED extends EntityDict & BaseEntityDict, T extends
|
|||
}
|
||||
declare abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feature {
|
||||
private zombie;
|
||||
protected stale?: boolean;
|
||||
/**
|
||||
* 当前有几个组件正在使用这个结点
|
||||
*/
|
||||
|
|
@ -68,6 +69,7 @@ declare abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feat
|
|||
isLoadingMore(): boolean;
|
||||
saveExtraData(key: string, data: any): void;
|
||||
loadExtraData(key: string): any;
|
||||
isStale(): boolean;
|
||||
abstract getParent(): Node<ED> | undefined;
|
||||
}
|
||||
declare abstract class EntityNode<ED extends EntityDict & BaseEntityDict, T extends keyof ED> extends Node<ED> {
|
||||
|
|
@ -107,7 +109,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
|
|||
}> | undefined;
|
||||
onCacheSync(records: OpRecord<ED>[]): void;
|
||||
destroy(): void;
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED>, path?: string, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], getTotal?: number, pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>);
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED>, path?: string, filters?: NamedFilterItem<ED, T>[], sorters?: NamedSorterItem<ED, T>[], getTotal?: number, pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>, stale?: boolean);
|
||||
getPagination(): Pagination;
|
||||
setPagination(pagination: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>, dontRefresh?: true): void;
|
||||
addChild(path: string, node: SingleNode<ED, T>): void;
|
||||
|
|
@ -190,7 +192,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
[K: string]: SingleNode<ED, keyof ED> | ListNode<ED, keyof ED>;
|
||||
};
|
||||
private filters?;
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, path: string, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED> | ListNode<ED, T>, id?: string, filters?: NamedFilterItem<ED, T>[]);
|
||||
constructor(entity: T, schema: StorageSchema<ED>, cache: Cache<ED>, path: string, projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>), parent?: SingleNode<ED, keyof ED> | VirtualNode<ED> | ListNode<ED, T>, id?: string, filters?: NamedFilterItem<ED, T>[], stale?: boolean);
|
||||
getModiOperations(): Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
@ -243,7 +245,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
|
|||
}
|
||||
declare class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<ED> {
|
||||
protected children: Record<string, SingleNode<ED, keyof ED> | ListNode<ED, keyof ED> | VirtualNode<ED>>;
|
||||
constructor(path?: string, parent?: VirtualNode<ED>);
|
||||
constructor(path?: string, parent?: VirtualNode<ED>, stale?: boolean);
|
||||
getModiOperations(): Array<{
|
||||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'];
|
||||
|
|
@ -278,6 +280,7 @@ export type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends
|
|||
afterExecute?: (operations: ED[T]['Operation'][]) => Promise<void>;
|
||||
id?: string;
|
||||
zombie: boolean;
|
||||
stale?: boolean;
|
||||
};
|
||||
export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature {
|
||||
private logSerailNumber;
|
||||
|
|
@ -310,8 +313,9 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
|
|||
isLoading(path: string): boolean | undefined;
|
||||
isLoadingMore(path: string): boolean | undefined;
|
||||
isExecuting(path: string): boolean;
|
||||
private isListDescandent;
|
||||
private isListDescandentOrStaleBranch;
|
||||
private isInModiNextBranch;
|
||||
needNotRefresh(path: string): boolean;
|
||||
refresh(path: string, pageNumber?: number): Promise<void>;
|
||||
loadMore(path: string): Promise<void>;
|
||||
getPagination(path: string): Pagination;
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ class UpdateLogManager {
|
|||
}
|
||||
class Node extends Feature_1.Feature {
|
||||
zombie = false;
|
||||
stale;
|
||||
/**
|
||||
* 当前有几个组件正在使用这个结点
|
||||
*/
|
||||
|
|
@ -252,6 +253,9 @@ class Node extends Feature_1.Feature {
|
|||
loadExtraData(key) {
|
||||
return this.extraData[key];
|
||||
}
|
||||
isStale() {
|
||||
return !!this.isStale;
|
||||
}
|
||||
}
|
||||
class EntityNode extends Node {
|
||||
entity;
|
||||
|
|
@ -545,7 +549,7 @@ class ListNode extends EntityNode {
|
|||
this.children[k].destroy();
|
||||
}
|
||||
}
|
||||
constructor(entity, schema, cache, projection, parent, path, filters, sorters, getTotal, pagination) {
|
||||
constructor(entity, schema, cache, projection, parent, path, filters, sorters, getTotal, pagination, stale) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.filters = filters || [];
|
||||
this.sorters = sorters || [];
|
||||
|
|
@ -558,6 +562,7 @@ class ListNode extends EntityNode {
|
|||
total: 0,
|
||||
count: 0,
|
||||
} : { ...DEFAULT_PAGINATION };
|
||||
this.stale = stale;
|
||||
this.syncHandler = (records) => this.onCacheSync(records);
|
||||
this.cache.bindOnSync(this.syncHandler);
|
||||
if (parent) {
|
||||
|
|
@ -1056,11 +1061,12 @@ class SingleNode extends EntityNode {
|
|||
sr;
|
||||
children;
|
||||
filters;
|
||||
constructor(entity, schema, cache, path, projection, parent, id, filters) {
|
||||
constructor(entity, schema, cache, path, projection, parent, id, filters, stale) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.children = {};
|
||||
this.sr = {};
|
||||
this.filters = filters;
|
||||
this.stale = stale;
|
||||
// addChild有可能为本结点赋上id值,所以要先行
|
||||
if (parent) {
|
||||
(0, assert_1.assert)(path);
|
||||
|
|
@ -1640,9 +1646,10 @@ class SingleNode extends EntityNode {
|
|||
}
|
||||
class VirtualNode extends Node {
|
||||
children;
|
||||
constructor(path, parent) {
|
||||
constructor(path, parent, stale) {
|
||||
super();
|
||||
this.children = {};
|
||||
this.stale = stale;
|
||||
if (parent) {
|
||||
parent.addChild(path, this);
|
||||
}
|
||||
|
|
@ -1796,7 +1803,7 @@ class RunningTree extends Feature_1.Feature {
|
|||
this.logSerailNumber = START_LSN;
|
||||
}
|
||||
createNode(options, isPage) {
|
||||
const { entity, pagination, path: fullPath, filters, sorters, projection, isList, id, getTotal, zombie, } = options;
|
||||
const { entity, pagination, path: fullPath, filters, sorters, projection, isList, id, getTotal, zombie, stale, } = options;
|
||||
let node;
|
||||
const { parent, path } = analyzePath(fullPath);
|
||||
const parentNode = parent ? this.findNode(parent) : undefined;
|
||||
|
|
@ -1863,16 +1870,16 @@ class RunningTree extends Feature_1.Feature {
|
|||
if (isList) {
|
||||
(0, assert_1.assert)(!(parentNode instanceof ListNode));
|
||||
// assert(projection, `页面没有定义投影「${path}」`);
|
||||
node = new ListNode(entity, this.schema, this.cache, projection, parentNode, path, filters, sorters, getTotal, pagination);
|
||||
node = new ListNode(entity, this.schema, this.cache, projection, parentNode, path, filters, sorters, getTotal, pagination, stale);
|
||||
}
|
||||
else {
|
||||
node = new SingleNode(entity, this.schema, this.cache, path, projection, parentNode, // 过编译
|
||||
id, filters);
|
||||
id, filters, stale);
|
||||
}
|
||||
}
|
||||
else {
|
||||
(0, assert_1.assert)(!parentNode || parentNode instanceof VirtualNode);
|
||||
node = new VirtualNode(path, parentNode);
|
||||
node = new VirtualNode(path, parentNode, stale);
|
||||
}
|
||||
if (!parentNode) {
|
||||
(0, assert_1.assert)(!parent && !this.root[path]);
|
||||
|
|
@ -2021,11 +2028,11 @@ class RunningTree extends Feature_1.Feature {
|
|||
const node = this.findNode(path);
|
||||
return node ? node.isExecuting() : false;
|
||||
}
|
||||
isListDescandent(path) {
|
||||
isListDescandentOrStaleBranch(path) {
|
||||
const node = this.findNode(path);
|
||||
let parent = node?.getParent();
|
||||
while (parent) {
|
||||
if (parent instanceof ListNode) {
|
||||
if (parent instanceof ListNode || parent.isStale()) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
|
|
@ -2079,10 +2086,10 @@ class RunningTree extends Feature_1.Feature {
|
|||
(0, assert_1.assert)(false);
|
||||
return false;
|
||||
}
|
||||
needNotRefresh(path) {
|
||||
return this.isListDescandentOrStaleBranch(path) || this.isInModiNextBranch(path);
|
||||
}
|
||||
async refresh(path, pageNumber) {
|
||||
if (this.isInModiNextBranch(path) || this.isListDescandent(path)) {
|
||||
return;
|
||||
}
|
||||
const node = this.findNode(path);
|
||||
if (!node?.isLoading()) {
|
||||
if (node instanceof ListNode) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ const uuid_1 = require("oak-domain/lib/utils/uuid");
|
|||
const row_1 = require("oak-domain/lib/utils/row");
|
||||
function onPathSet(option, isPage) {
|
||||
const { props, state } = this;
|
||||
const { oakPath, oakId, oakFilters, oakZombie } = props;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal } = option;
|
||||
const { oakPath, oakId, oakFilters, oakZombie, oakStale } = props;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal, stale } = option;
|
||||
const { features } = this;
|
||||
(0, assert_1.assert)(isPage || zombie === undefined, 'zombie只在页面级别声明');
|
||||
(0, assert_1.assert)(isPage || path === undefined, 'path只在页面级别自动声明');
|
||||
|
|
@ -112,6 +112,7 @@ function onPathSet(option, isPage) {
|
|||
// cascadeActions: cascadeActions && (() => cascadeActions.call(this)),
|
||||
getTotal: getTotal2,
|
||||
zombie: isPage ? !!zombie : !!oakZombie,
|
||||
stale: !!oakStale || !!stale,
|
||||
}, isPage);
|
||||
this.addFeatureSub('runningTree', (path2) => {
|
||||
// 父结点改变,子结点要重渲染
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ const oakBehavior = Behavior({
|
|||
this.oakOption.lifetimes?.ready &&
|
||||
this.oakOption.lifetimes?.ready.call(this);
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !this.oakOption.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
@ -791,7 +791,7 @@ function createComponent(option, features) {
|
|||
return;
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
try {
|
||||
await this.refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ function createComponent(option, features) {
|
|||
}
|
||||
try {
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
await this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
@ -709,7 +709,7 @@ function createComponent(option, features) {
|
|||
lifetimes?.show && lifetimes.show.call(this);
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ type OakComponentProperties<ED extends EntityDict & BaseEntityDict, T extends ke
|
|||
oakParentEntity: string;
|
||||
oakDisablePulldownRefresh: boolean;
|
||||
oakZombie: boolean;
|
||||
oakStale: boolean;
|
||||
oakAutoUnmount: boolean;
|
||||
oakActions: string;
|
||||
oakCascadeActions: string;
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ class UpdateLogManager<ED extends EntityDict & BaseEntityDict, T extends keyof E
|
|||
|
||||
abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feature {
|
||||
private zombie: boolean = false;
|
||||
protected stale?: boolean;
|
||||
/**
|
||||
* 当前有几个组件正在使用这个结点
|
||||
*/
|
||||
|
|
@ -323,6 +324,10 @@ abstract class Node<ED extends EntityDict & BaseEntityDict> extends Feature {
|
|||
return this.extraData[key];
|
||||
}
|
||||
|
||||
isStale() {
|
||||
return !!this.isStale;
|
||||
}
|
||||
|
||||
abstract getParent(): Node<ED> | undefined;
|
||||
}
|
||||
|
||||
|
|
@ -678,7 +683,8 @@ class ListNode<
|
|||
filters?: NamedFilterItem<ED, T>[],
|
||||
sorters?: NamedSorterItem<ED, T>[],
|
||||
getTotal?: number,
|
||||
pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>
|
||||
pagination?: Pick<Pagination, 'currentPage' | 'pageSize' | 'randomRange'>,
|
||||
stale?: boolean
|
||||
) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.filters = filters || [];
|
||||
|
|
@ -692,6 +698,7 @@ class ListNode<
|
|||
total: 0,
|
||||
count: 0,
|
||||
} : { ...DEFAULT_PAGINATION };
|
||||
this.stale = stale;
|
||||
|
||||
this.syncHandler = (records) => this.onCacheSync(records);
|
||||
this.cache.bindOnSync(this.syncHandler);
|
||||
|
|
@ -1315,12 +1322,14 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
projection?: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>),
|
||||
parent?: SingleNode<ED, keyof ED> | VirtualNode<ED> | ListNode<ED, T>,
|
||||
id?: string,
|
||||
filters?: NamedFilterItem<ED, T>[]
|
||||
filters?: NamedFilterItem<ED, T>[],
|
||||
stale?: boolean
|
||||
) {
|
||||
super(entity, schema, cache, projection, parent);
|
||||
this.children = {};
|
||||
this.sr = {};
|
||||
this.filters = filters;
|
||||
this.stale = stale;
|
||||
|
||||
// addChild有可能为本结点赋上id值,所以要先行
|
||||
if (parent) {
|
||||
|
|
@ -1959,9 +1968,10 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
|
|||
|
||||
class VirtualNode<ED extends EntityDict & BaseEntityDict> extends Node<ED> {
|
||||
protected children: Record<string, SingleNode<ED, keyof ED> | ListNode<ED, keyof ED> | VirtualNode<ED>>;
|
||||
constructor(path?: string, parent?: VirtualNode<ED>) {
|
||||
constructor(path?: string, parent?: VirtualNode<ED>, stale?: boolean) {
|
||||
super();
|
||||
this.children = {};
|
||||
this.stale = stale;
|
||||
if (parent) {
|
||||
parent.addChild(path!, this);
|
||||
}
|
||||
|
|
@ -2123,6 +2133,7 @@ export type CreateNodeOptions<ED extends EntityDict & BaseEntityDict, T extends
|
|||
afterExecute?: (operations: ED[T]['Operation'][]) => Promise<void>;
|
||||
id?: string;
|
||||
zombie: boolean;
|
||||
stale?: boolean;
|
||||
// createData?: CreateDataDef<ED, T>; // 暂不支持
|
||||
};
|
||||
|
||||
|
|
@ -2173,6 +2184,7 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
id,
|
||||
getTotal,
|
||||
zombie,
|
||||
stale,
|
||||
} = options;
|
||||
let node: ListNode<ED, T> | SingleNode<ED, T> | VirtualNode<ED> | undefined;
|
||||
const { parent, path } = analyzePath(fullPath);
|
||||
|
|
@ -2255,7 +2267,8 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
filters,
|
||||
sorters,
|
||||
getTotal,
|
||||
pagination
|
||||
pagination,
|
||||
stale,
|
||||
);
|
||||
} else {
|
||||
node = new SingleNode<ED, T>(
|
||||
|
|
@ -2266,12 +2279,13 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
projection,
|
||||
parentNode as VirtualNode<ED>, // 过编译
|
||||
id,
|
||||
filters
|
||||
filters,
|
||||
stale
|
||||
);
|
||||
}
|
||||
} else {
|
||||
assert(!parentNode || parentNode instanceof VirtualNode);
|
||||
node = new VirtualNode(path, parentNode);
|
||||
node = new VirtualNode(path, parentNode, stale);
|
||||
}
|
||||
if (!parentNode) {
|
||||
assert(!parent && !this.root[path]);
|
||||
|
|
@ -2466,11 +2480,11 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
return node ? node.isExecuting() : false;
|
||||
}
|
||||
|
||||
private isListDescandent(path: string) {
|
||||
private isListDescandentOrStaleBranch(path: string) {
|
||||
const node = this.findNode(path);
|
||||
let parent = node?.getParent();
|
||||
while (parent) {
|
||||
if (parent instanceof ListNode) {
|
||||
if (parent instanceof ListNode || parent.isStale()) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
|
|
@ -2480,7 +2494,7 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
|
||||
// 判断当前结点是否在:next的路径上
|
||||
// 当前判断规则是:在:next的分岔结点上,如果有前项结点,或者:next结点本身是一个create,则不再刷新
|
||||
private isInModiNextBranch(path: string) {
|
||||
private isInModiNextBranch(path: string) {
|
||||
if (!path.includes(MODI_NEXT_PATH_SUFFIX)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2531,10 +2545,11 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
|
|||
return false;
|
||||
}
|
||||
|
||||
needNotRefresh(path: string) {
|
||||
return this.isListDescandentOrStaleBranch(path) || this.isInModiNextBranch(path);
|
||||
}
|
||||
|
||||
async refresh(path: string, pageNumber?: number) {
|
||||
if (this.isInModiNextBranch(path) || this.isListDescandent(path)) {
|
||||
return;
|
||||
}
|
||||
const node = this.findNode(path);
|
||||
if (!node?.isLoading()) {
|
||||
if (node instanceof ListNode) {
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ export function onPathSet<
|
|||
option: OakComponentOption<any, ED, T, Cxt, FrontCxt, any, any, any, {}, {}, {}>,
|
||||
isPage: boolean): Partial<OakComponentData<ED, T>> {
|
||||
const { props, state } = this;
|
||||
const { oakPath, oakId, oakFilters, oakZombie } = props as ComponentProps<ED, T, {}>;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal } = option;
|
||||
const { oakPath, oakId, oakFilters, oakZombie, oakStale } = props as ComponentProps<ED, T, {}>;
|
||||
const { zombie, entity, path, projection, isList, filters, sorters, pagination, getTotal, stale } = option;
|
||||
const { features } = this;
|
||||
|
||||
assert(isPage || zombie === undefined, 'zombie只在页面级别声明');
|
||||
|
|
@ -151,6 +151,7 @@ export function onPathSet<
|
|||
// cascadeActions: cascadeActions && (() => cascadeActions.call(this)),
|
||||
getTotal: getTotal2,
|
||||
zombie: isPage ? !!zombie : !!oakZombie,
|
||||
stale: !!oakStale || !!stale,
|
||||
}, isPage);
|
||||
this.addFeatureSub('runningTree', (path2: string) => {
|
||||
// 父结点改变,子结点要重渲染
|
||||
|
|
|
|||
|
|
@ -709,7 +709,7 @@ const oakBehavior = Behavior<
|
|||
this.oakOption.lifetimes?.ready.call(this);
|
||||
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !this.oakOption.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
} else {
|
||||
this.reRender();
|
||||
|
|
@ -1113,7 +1113,7 @@ export function createComponent<
|
|||
return;
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
try {
|
||||
await this.refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -979,7 +979,7 @@ export function createComponent<
|
|||
|
||||
try {
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
await this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
@ -1047,7 +1047,7 @@ export function createComponent<
|
|||
lifetimes?.show && lifetimes.show.call(this);
|
||||
}
|
||||
const { oakFullpath } = this.state;
|
||||
if (oakFullpath && !option.stale) {
|
||||
if (oakFullpath && !this.features.runningTree.needNotRefresh(oakFullpath)) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ type OakComponentProperties<
|
|||
oakParentEntity: string;
|
||||
oakDisablePulldownRefresh: boolean;
|
||||
oakZombie: boolean; // 表示页面unmount时不析构runningTree上的数据
|
||||
oakStale: boolean; // 表示页面不需要主动刷新数据
|
||||
oakAutoUnmount: boolean; // 原先需要手动让component卸载,已经废弃
|
||||
oakActions: string;
|
||||
oakCascadeActions: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue