Merge branch 'dev' into release

This commit is contained in:
Xu Chang 2025-01-08 21:27:05 +08:00
commit 0452132b2b
17 changed files with 248 additions and 79 deletions

View File

@ -10,8 +10,7 @@
} }
.block--bottom { .block--bottom {
width: 100vw; width: 100%;
height: 35vh;
border-top-left-radius: 16rpx; border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx; border-top-right-radius: 16rpx;
} }

View File

@ -179,7 +179,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
* *
*/ */
saveRefreshResult(sr: Awaited<ReturnType<CommonAspectDict<ED>['select']>>, append?: boolean, currentPage?: number): void; saveRefreshResult(sr: Awaited<ReturnType<CommonAspectDict<ED>['select']>>, append?: boolean, currentPage?: number): void;
refresh(pageNumber?: number, append?: boolean, resetTotal?: number): Promise<void>; refresh(pageNumber?: number, append?: boolean, resetTotal?: boolean): Promise<void>;
loadMore(): Promise<void>; loadMore(): Promise<void>;
setCurrentPage(currentPage: number): void; setCurrentPage(currentPage: number): void;
clean(lsn?: number, dontPublish?: true): void; clean(lsn?: number, dontPublish?: true): void;
@ -313,7 +313,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
isLoading(path: string): boolean | undefined; isLoading(path: string): boolean | undefined;
isLoadingMore(path: string): boolean | undefined; isLoadingMore(path: string): boolean | undefined;
isExecuting(path: string): boolean; isExecuting(path: string): boolean;
isListDescandentOrStaleBranch(path: string): boolean; isListDescandentOrStale(path: string): boolean;
private isInModiNextBranch; private isInModiNextBranch;
refresh(path: string, pageNumber?: number): Promise<void>; refresh(path: string, pageNumber?: number): Promise<void>;
loadMore(path: string): Promise<void>; loadMore(path: string): Promise<void>;

View File

@ -1,5 +1,5 @@
import { assert } from 'oak-domain/lib/utils/assert'; import { assert } from 'oak-domain/lib/utils/assert';
import { cloneDeep, unset, uniq } from "oak-domain/lib/utils/lodash"; import { cloneDeep, difference, unset, uniq, intersection } from "oak-domain/lib/utils/lodash";
import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter"; import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter";
import { createOperationsFromModies } from 'oak-domain/lib/store/modi'; import { createOperationsFromModies } from 'oak-domain/lib/store/modi';
import { judgeRelation } from "oak-domain/lib/store/relation"; import { judgeRelation } from "oak-domain/lib/store/relation";
@ -417,8 +417,7 @@ class ListNode extends EntityNode {
} }
} }
onCacheSync(records) { onCacheSync(records) {
// 只需要处理当listNode为首页且插入/删除项满足条件的情况 if (this.loading) {
if (this.loading || this.pagination.currentPage !== 0) {
return; return;
} }
// let hasUpdated = false; // let hasUpdated = false;
@ -507,6 +506,50 @@ class ListNode extends EntityNode {
} }
case 'u': case 'u':
default: { default: {
// 更新可能会引起本行不再满足条件
const { e, d, f } = record;
if (e === this.entity) {
const { id } = f;
const ids = typeof id === 'string' ? [id] : id.$in;
const currentIds = Object.keys(this.sr);
const intersected = intersection(ids, currentIds);
const diffed = difference(ids, currentIds);
/**
* 以及原本不在的现在是不是满足条件了
* 后一种情况也可能原本就满足但不在当前的ids中这时是判断不出来的total+1可能不对但是应该是较少的case*/
const filter = this.constructFilters(true, true, true);
if (intersected.length) {
const rows = this.cache.get(this.entity, {
data: {
id: 1,
},
filter: combineFilters(this.entity, this.schema, [
...filter,
{
id: {
$in: intersected,
}
}
])
});
const rowIds = rows.map(ele => ele.id);
const missed = difference(intersected, rowIds);
missed.forEach((id) => {
unset(this.sr, id);
if (this.pagination.total) {
this.pagination.total--;
}
});
}
if (diffed.length) {
diffed.forEach((ele) => {
this.sr[ele] = {};
if (this.pagination.total) {
this.pagination.total++;
}
});
}
}
// hasUpdated = true; // hasUpdated = true;
break; break;
} }
@ -630,6 +673,7 @@ class ListNode extends EntityNode {
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} }
@ -643,6 +687,7 @@ class ListNode extends EntityNode {
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} }
@ -1182,11 +1227,15 @@ class SingleNode extends EntityNode {
const operations = this.ulManager.makeOperations(); const operations = this.ulManager.makeOperations();
assert(operations.length <= 1); assert(operations.length <= 1);
const [operation] = operations; const [operation] = operations;
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
if (operation?.action === 'create') { if (operation?.action === 'create') {
if (operation.data.id === id) { if (operation.data.id === id) {
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
return; return;
} }
else {
// 这种情况是oakId属性没有初始化完成
this.clean(0, true);
}
} }
assert(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update'); assert(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update');
this.id = id; this.id = id;
@ -1934,7 +1983,10 @@ export class RunningTree extends Feature {
}); });
} }
node.increaseCount(); node.increaseCount();
if (zombie) {
// 像Pagination, FilterPanel, ExtrafileCommit这种要和某个Component共用路径的按要求都应该是后创建不能影响原来的zombie
node.setZombie(zombie); node.setZombie(zombie);
}
if (node instanceof SingleNode && !node.getId()) { if (node instanceof SingleNode && !node.getId()) {
node.create(this.logSerailNumber, {}); node.create(this.logSerailNumber, {});
} }
@ -2085,11 +2137,14 @@ export class RunningTree extends Feature {
const node = this.findNode(path); const node = this.findNode(path);
return node ? node.isExecuting() : false; return node ? node.isExecuting() : false;
} }
isListDescandentOrStaleBranch(path) { isListDescandentOrStale(path) {
const node = this.findNode(path); const node = this.findNode(path);
if (node?.isStale()) {
return true;
}
let parent = node?.getParent(); let parent = node?.getParent();
while (parent) { while (parent) {
if (parent instanceof ListNode || parent.isStale()) { if (parent instanceof ListNode) {
return true; return true;
} }
parent = parent.getParent(); parent = parent.getParent();

View File

@ -442,10 +442,10 @@ export function reRender(option, extra) {
const entity = this.features.runningTree.getEntity(this.state.oakFullpath); const entity = this.features.runningTree.getEntity(this.state.oakFullpath);
if (origin) { if (origin) {
if (rows instanceof Array) { if (rows instanceof Array) {
modified = compareRows(schema, entity, rows, origin); modified = !compareRows(schema, entity, rows, origin);
} }
else { else {
modified = compareRow(schema, entity, rows, origin); modified = !compareRow(schema, entity, rows, origin);
} }
} }
else { else {

View File

@ -197,7 +197,7 @@ const oakBehavior = Behavior({
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -485,7 +485,7 @@ const oakBehavior = Behavior({
this.oakOption.lifetimes?.ready && this.oakOption.lifetimes?.ready &&
this.oakOption.lifetimes?.ready.call(this); this.oakOption.lifetimes?.ready.call(this);
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} }
else { else {
@ -788,7 +788,7 @@ export function createComponent(option, features) {
return; return;
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
try { try {
await this.refresh(); await this.refresh();
} }

View File

@ -187,7 +187,7 @@ class OakComponentBase extends React.PureComponent {
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -646,7 +646,7 @@ export function createComponent(option, features) {
} }
try { try {
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
await this.refresh(); await this.refresh();
} }
else { else {
@ -704,7 +704,7 @@ export function createComponent(option, features) {
lifetimes?.show && lifetimes.show.call(this); lifetimes?.show && lifetimes.show.call(this);
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} }
else { else {

View File

@ -179,7 +179,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
* *
*/ */
saveRefreshResult(sr: Awaited<ReturnType<CommonAspectDict<ED>['select']>>, append?: boolean, currentPage?: number): void; saveRefreshResult(sr: Awaited<ReturnType<CommonAspectDict<ED>['select']>>, append?: boolean, currentPage?: number): void;
refresh(pageNumber?: number, append?: boolean, resetTotal?: number): Promise<void>; refresh(pageNumber?: number, append?: boolean, resetTotal?: boolean): Promise<void>;
loadMore(): Promise<void>; loadMore(): Promise<void>;
setCurrentPage(currentPage: number): void; setCurrentPage(currentPage: number): void;
clean(lsn?: number, dontPublish?: true): void; clean(lsn?: number, dontPublish?: true): void;
@ -313,7 +313,7 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict> extends
isLoading(path: string): boolean | undefined; isLoading(path: string): boolean | undefined;
isLoadingMore(path: string): boolean | undefined; isLoadingMore(path: string): boolean | undefined;
isExecuting(path: string): boolean; isExecuting(path: string): boolean;
isListDescandentOrStaleBranch(path: string): boolean; isListDescandentOrStale(path: string): boolean;
private isInModiNextBranch; private isInModiNextBranch;
refresh(path: string, pageNumber?: number): Promise<void>; refresh(path: string, pageNumber?: number): Promise<void>;
loadMore(path: string): Promise<void>; loadMore(path: string): Promise<void>;

View File

@ -420,8 +420,7 @@ class ListNode extends EntityNode {
} }
} }
onCacheSync(records) { onCacheSync(records) {
// 只需要处理当listNode为首页且插入/删除项满足条件的情况 if (this.loading) {
if (this.loading || this.pagination.currentPage !== 0) {
return; return;
} }
// let hasUpdated = false; // let hasUpdated = false;
@ -510,6 +509,50 @@ class ListNode extends EntityNode {
} }
case 'u': case 'u':
default: { default: {
// 更新可能会引起本行不再满足条件
const { e, d, f } = record;
if (e === this.entity) {
const { id } = f;
const ids = typeof id === 'string' ? [id] : id.$in;
const currentIds = Object.keys(this.sr);
const intersected = (0, lodash_1.intersection)(ids, currentIds);
const diffed = (0, lodash_1.difference)(ids, currentIds);
/**
* 以及原本不在的现在是不是满足条件了
* 后一种情况也可能原本就满足但不在当前的ids中这时是判断不出来的total+1可能不对但是应该是较少的case*/
const filter = this.constructFilters(true, true, true);
if (intersected.length) {
const rows = this.cache.get(this.entity, {
data: {
id: 1,
},
filter: (0, filter_1.combineFilters)(this.entity, this.schema, [
...filter,
{
id: {
$in: intersected,
}
}
])
});
const rowIds = rows.map(ele => ele.id);
const missed = (0, lodash_1.difference)(intersected, rowIds);
missed.forEach((id) => {
(0, lodash_1.unset)(this.sr, id);
if (this.pagination.total) {
this.pagination.total--;
}
});
}
if (diffed.length) {
diffed.forEach((ele) => {
this.sr[ele] = {};
if (this.pagination.total) {
this.pagination.total++;
}
});
}
}
// hasUpdated = true; // hasUpdated = true;
break; break;
} }
@ -633,6 +676,7 @@ class ListNode extends EntityNode {
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} }
@ -646,6 +690,7 @@ class ListNode extends EntityNode {
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} }
@ -1185,11 +1230,15 @@ class SingleNode extends EntityNode {
const operations = this.ulManager.makeOperations(); const operations = this.ulManager.makeOperations();
(0, assert_1.assert)(operations.length <= 1); (0, assert_1.assert)(operations.length <= 1);
const [operation] = operations; const [operation] = operations;
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
if (operation?.action === 'create') { if (operation?.action === 'create') {
if (operation.data.id === id) { if (operation.data.id === id) {
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
return; return;
} }
else {
// 这种情况是oakId属性没有初始化完成
this.clean(0, true);
}
} }
(0, assert_1.assert)(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update'); (0, assert_1.assert)(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update');
this.id = id; this.id = id;
@ -1937,7 +1986,10 @@ class RunningTree extends Feature_1.Feature {
}); });
} }
node.increaseCount(); node.increaseCount();
if (zombie) {
// 像Pagination, FilterPanel, ExtrafileCommit这种要和某个Component共用路径的按要求都应该是后创建不能影响原来的zombie
node.setZombie(zombie); node.setZombie(zombie);
}
if (node instanceof SingleNode && !node.getId()) { if (node instanceof SingleNode && !node.getId()) {
node.create(this.logSerailNumber, {}); node.create(this.logSerailNumber, {});
} }
@ -2088,11 +2140,14 @@ class RunningTree extends Feature_1.Feature {
const node = this.findNode(path); const node = this.findNode(path);
return node ? node.isExecuting() : false; return node ? node.isExecuting() : false;
} }
isListDescandentOrStaleBranch(path) { isListDescandentOrStale(path) {
const node = this.findNode(path); const node = this.findNode(path);
if (node?.isStale()) {
return true;
}
let parent = node?.getParent(); let parent = node?.getParent();
while (parent) { while (parent) {
if (parent instanceof ListNode || parent.isStale()) { if (parent instanceof ListNode) {
return true; return true;
} }
parent = parent.getParent(); parent = parent.getParent();

View File

@ -446,10 +446,10 @@ function reRender(option, extra) {
const entity = this.features.runningTree.getEntity(this.state.oakFullpath); const entity = this.features.runningTree.getEntity(this.state.oakFullpath);
if (origin) { if (origin) {
if (rows instanceof Array) { if (rows instanceof Array) {
modified = (0, row_1.compareRows)(schema, entity, rows, origin); modified = !(0, row_1.compareRows)(schema, entity, rows, origin);
} }
else { else {
modified = (0, row_1.compareRow)(schema, entity, rows, origin); modified = !(0, row_1.compareRow)(schema, entity, rows, origin);
} }
} }
else { else {

View File

@ -200,7 +200,7 @@ const oakBehavior = Behavior({
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -488,7 +488,7 @@ const oakBehavior = Behavior({
this.oakOption.lifetimes?.ready && this.oakOption.lifetimes?.ready &&
this.oakOption.lifetimes?.ready.call(this); this.oakOption.lifetimes?.ready.call(this);
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} }
else { else {
@ -791,7 +791,7 @@ function createComponent(option, features) {
return; return;
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
try { try {
await this.refresh(); await this.refresh();
} }

View File

@ -192,7 +192,7 @@ class OakComponentBase extends react_1.default.PureComponent {
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -651,7 +651,7 @@ function createComponent(option, features) {
} }
try { try {
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
await this.refresh(); await this.refresh();
} }
else { else {
@ -709,7 +709,7 @@ function createComponent(option, features) {
lifetimes?.show && lifetimes.show.call(this); lifetimes?.show && lifetimes.show.call(this);
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} }
else { else {

View File

@ -1,6 +1,6 @@
{ {
"name": "oak-frontend-base", "name": "oak-frontend-base",
"version": "5.3.23", "version": "5.3.24",
"description": "oak框架中前端与业务逻辑无关的平台部分", "description": "oak框架中前端与业务逻辑无关的平台部分",
"author": { "author": {
"name": "XuChang" "name": "XuChang"
@ -23,8 +23,8 @@
"node-schedule": "^2.1.1", "node-schedule": "^2.1.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"oak-common-aspect": "^3.0.5", "oak-common-aspect": "^3.0.5",
"oak-domain": "^5.1.15", "oak-domain": "^5.1.16",
"oak-memory-tree-store": "^3.3.8", "oak-memory-tree-store": "^3.3.9",
"ol": "^7.3.0", "ol": "^7.3.0",
"rc-pagination": "^4.3.0", "rc-pagination": "^4.3.0",
"react-activation": "^0.12.4", "react-activation": "^0.12.4",
@ -64,7 +64,7 @@
"@types/node": "^20.7.0", "@types/node": "^20.7.0",
"@types/node-schedule": "^2.1.0", "@types/node-schedule": "^2.1.0",
"@types/nprogress": "^0.2.3", "@types/nprogress": "^0.2.3",
"@types/react": "^18.3.17", "@types/react": "^18.3.18",
"@types/react-dom": "^18.2.14", "@types/react-dom": "^18.2.14",
"@types/react-native": "^0.72.8", "@types/react-native": "^0.72.8",
"@types/uuid": "^9.0.6", "@types/uuid": "^9.0.6",

View File

@ -10,8 +10,7 @@
} }
.block--bottom { .block--bottom {
width: 100vw; width: 100%;
height: 35vh;
border-top-left-radius: 16rpx; border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx; border-top-right-radius: 16rpx;
} }

View File

@ -1,5 +1,5 @@
import { assert } from 'oak-domain/lib/utils/assert'; import { assert } from 'oak-domain/lib/utils/assert';
import { cloneDeep, difference, unset, merge, uniq, omit } from "oak-domain/lib/utils/lodash"; import { cloneDeep, difference, unset, merge, uniq, omit, intersection } from "oak-domain/lib/utils/lodash";
import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter"; import { combineFilters, getRelevantIds } from "oak-domain/lib/store/filter";
import { createOperationsFromModies } from 'oak-domain/lib/store/modi'; import { createOperationsFromModies } from 'oak-domain/lib/store/modi';
import { judgeRelation } from "oak-domain/lib/store/relation"; import { judgeRelation } from "oak-domain/lib/store/relation";
@ -534,8 +534,7 @@ class ListNode<
} }
onCacheSync(records: OpRecord<ED>[]) { onCacheSync(records: OpRecord<ED>[]) {
// 只需要处理当listNode为首页且插入/删除项满足条件的情况 if (this.loading) {
if (this.loading || this.pagination.currentPage !== 0) {
return; return;
} }
// let hasUpdated = false; // let hasUpdated = false;
@ -628,6 +627,56 @@ class ListNode<
} }
case 'u': case 'u':
default: { default: {
// 更新可能会引起本行不再满足条件
const { e, d, f } = record as UpdateOpResult<ED, keyof ED>;
if (e === this.entity) {
const { id } = f!;
const ids: string[] = typeof id === 'string' ? [id] : id.$in;
const currentIds = Object.keys(this.sr);
const intersected = intersection(ids, currentIds);
const diffed = difference(ids, currentIds);
/**
*
* ids中total+1case*/
const filter = this.constructFilters(true, true, true);
if (intersected.length) {
const rows = this.cache.get(this.entity, {
data: {
id: 1,
},
filter: combineFilters(this.entity, this.schema, [
...filter!,
{
id: {
$in: intersected,
}
}
])
});
const rowIds = rows.map(ele => ele.id!);
const missed = difference(intersected, rowIds);
missed.forEach(
(id) => {
unset(this.sr, id);
if (this.pagination.total) {
this.pagination.total --;
}
}
);
}
if (diffed.length) {
diffed.forEach(
(ele) => {
this.sr[ele] = {};
if (this.pagination.total) {
this.pagination.total ++;
}
}
);
}
}
// hasUpdated = true; // hasUpdated = true;
break; break;
} }
@ -784,6 +833,7 @@ class ListNode<
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} else { } else {
@ -797,6 +847,7 @@ class ListNode<
if (fIndex >= 0) { if (fIndex >= 0) {
this.filters.splice(fIndex, 1); this.filters.splice(fIndex, 1);
} }
this.pagination.total = undefined;
if (refresh) { if (refresh) {
this.refresh(0, false); this.refresh(0, false);
} else { } else {
@ -1208,7 +1259,7 @@ class ListNode<
// this.publish(); // this.publish();
} }
async refresh(pageNumber?: number, append?: boolean, resetTotal?: number) { async refresh(pageNumber?: number, append?: boolean, resetTotal?: boolean) {
if (resetTotal) { if (resetTotal) {
// 清空之前查询计算的total值目前只有父结点id改变会这样调用 // 清空之前查询计算的total值目前只有父结点id改变会这样调用
this.pagination.total = undefined; this.pagination.total = undefined;
@ -1466,11 +1517,15 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
const operations = this.ulManager.makeOperations(); const operations = this.ulManager.makeOperations();
assert(operations.length <= 1); assert(operations.length <= 1);
const [operation] = operations; const [operation] = operations;
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
if (operation?.action === 'create') { if (operation?.action === 'create') {
if (operation.data.id === id) { if (operation.data.id === id) {
// 如果本身是create 这里无视就行(因为框架原因会调用一次)
return; return;
} }
else {
// 这种情况是oakId属性没有初始化完成
this.clean(0, true);
}
} }
assert(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update'); assert(!this.dirty, 'setId时结点是dirty在setId之前应当处理掉原有的update');
this.id = id; this.id = id;
@ -2352,7 +2407,10 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
} }
node.increaseCount(); node.increaseCount();
if (zombie) {
// 像Pagination, FilterPanel, ExtrafileCommit这种要和某个Component共用路径的按要求都应该是后创建不能影响原来的zombie
node.setZombie(zombie); node.setZombie(zombie);
}
if (node instanceof SingleNode && !node.getId()) { if (node instanceof SingleNode && !node.getId()) {
node.create(this.logSerailNumber, {}); node.create(this.logSerailNumber, {});
} }
@ -2545,11 +2603,14 @@ export class RunningTree<ED extends EntityDict & BaseEntityDict> extends Feature
return node ? node.isExecuting() : false; return node ? node.isExecuting() : false;
} }
isListDescandentOrStaleBranch(path: string) { isListDescandentOrStale(path: string) {
const node = this.findNode(path); const node = this.findNode(path);
if (node?.isStale()) {
return true;
}
let parent = node?.getParent(); let parent = node?.getParent();
while (parent) { while (parent) {
if (parent instanceof ListNode || parent.isStale()) { if (parent instanceof ListNode) {
return true; return true;
} }
parent = parent.getParent(); parent = parent.getParent();

View File

@ -547,10 +547,10 @@ export function reRender<
const entity = this.features.runningTree.getEntity(this.state.oakFullpath); const entity = this.features.runningTree.getEntity(this.state.oakFullpath);
if (origin) { if (origin) {
if (rows instanceof Array) { if (rows instanceof Array) {
modified = compareRows(schema, entity, rows, origin as typeof rows); modified = !compareRows(schema, entity, rows, origin as typeof rows);
} }
else { else {
modified = compareRow(schema, entity, rows!, origin as NonNullable<typeof rows>); modified = !compareRow(schema, entity, rows!, origin as NonNullable<typeof rows>);
} }
} }
else { else {

View File

@ -332,7 +332,7 @@ const oakBehavior = Behavior<
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -709,7 +709,7 @@ const oakBehavior = Behavior<
this.oakOption.lifetimes?.ready.call(this); this.oakOption.lifetimes?.ready.call(this);
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} else { } else {
this.reRender(); this.reRender();
@ -1113,7 +1113,7 @@ export function createComponent<
return; return;
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
try { try {
await this.refresh(); await this.refresh();
} }

View File

@ -368,7 +368,7 @@ abstract class OakComponentBase<
? `${this.state.oakFullpath}.${path}` ? `${this.state.oakFullpath}.${path}`
: this.state.oakFullpath; : this.state.oakFullpath;
const operations = this.features.runningTree.getOperations(path2); const operations = this.features.runningTree.getOperations(path2);
if (operations) { if (operations?.length) {
for (const oper of operations) { for (const oper of operations) {
const { entity, operation } = oper; const { entity, operation } = oper;
const operation2 = action ? { const operation2 = action ? {
@ -979,7 +979,7 @@ export function createComponent<
try { try {
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
await this.refresh(); await this.refresh();
} }
else { else {
@ -1047,7 +1047,7 @@ export function createComponent<
lifetimes?.show && lifetimes.show.call(this); lifetimes?.show && lifetimes.show.call(this);
} }
const { oakFullpath } = this.state; const { oakFullpath } = this.state;
if (oakFullpath && !this.features.runningTree.isListDescandentOrStaleBranch(oakFullpath)) { if (oakFullpath && !this.features.runningTree.isListDescandentOrStale(oakFullpath)) {
this.refresh(); this.refresh();
} }
else { else {