在update数据时,将空字符串当作null处理

This commit is contained in:
Xu Chang 2023-10-08 13:32:38 +08:00
parent f97989998b
commit bbe15c5e86
15 changed files with 126 additions and 21 deletions

View File

@ -107,8 +107,10 @@ function initializeWatchers(store, contextBuilder, watchers) {
dontCollect: true,
blockTrigger: true,
});
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
if (rows.length > 0) {
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
}
}
await context.commit();
}

View File

@ -470,6 +470,14 @@ class ListNode extends Node {
}, this.isLoading()); */
}
addItem(item, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in item) {
if (item[k] === '') {
Object.assign(item, {
[k]: null,
});
}
}
const id = generateNewId();
assert(!this.updates[id]);
this.updates[id] = {
@ -527,6 +535,14 @@ class ListNode extends Node {
* @param afterExecute
*/
updateItem(data, id, action, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
// assert(Object.keys(this.children).length === 0, `更新子结点应该落在相应的component上`);
if (this.children && this.children[id]) {
// 实际中有这样的case出现当使用actionButton时。先这样处理。by Xc 20230214
@ -937,6 +953,14 @@ class SingleNode extends Node {
create(data, beforeExecute, afterExecute) {
const id = generateNewId();
assert(!this.id && !this.dirty, 'create前要保证singleNode为空');
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
this.operation = {
operation: {
id: generateNewId(),
@ -949,6 +973,14 @@ class SingleNode extends Node {
this.setDirty();
}
update(data, action, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
if (!this.operation) {
if (this.id) {
const operation = {

View File

@ -22,7 +22,7 @@ import { InitializeOptions } from './types/Initialize';
*/
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, backendContextBuilder: (contextStr?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, aspectDict: AD, triggers: Array<Trigger<ED, keyof ED, Cxt>>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, watchers: Array<Watcher<ED, keyof ED, Cxt>>, timers: Array<Timer<ED, Cxt>>, startRoutines: Array<Routine<ED, Cxt>>, initialData: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
}, option: InitializeOptions<ED>): {
}, option: InitializeOptions<ED, Cxt>): {
features: {
cache: import(".").Cache<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
relationAuth: import("./features/relationAuth").RelationAuth<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;

View File

@ -19,7 +19,7 @@ import { InitializeOptions } from './types/Initialize';
* @param actionDict
* @returns
*/
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, connector: Connector<ED, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED>): {
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, connector: Connector<ED, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED, Cxt>): {
features: {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;

View File

@ -1,14 +1,15 @@
import { AsyncContext } from 'oak-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { ActionDictOfEntityDict, ColorDict, Importation, Exportation } from 'oak-domain/lib/types';
import { AuthCascadePath, AuthDeduceRelationMap, EntityDict } from 'oak-domain/lib/types/Entity';
export type InitializeOptions<ED extends EntityDict & BaseEntityDict> = {
export type InitializeOptions<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
actionDict: ActionDictOfEntityDict<ED>;
actionCascadePathGraph: AuthCascadePath<ED>[];
relationCascadePathGraph: AuthCascadePath<ED>[];
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
colorDict: ColorDict<ED>;
importations?: Importation<ED, keyof ED, any>[];
exportations?: Exportation<ED, keyof ED, any>[];
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
createFreeEntities?: (keyof ED)[];
updateFreeEntities?: (keyof ED)[];

View File

@ -111,8 +111,10 @@ function initializeWatchers(store, contextBuilder, watchers) {
dontCollect: true,
blockTrigger: true,
});
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
if (rows.length > 0) {
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
}
}
await context.commit();
}

View File

@ -473,6 +473,14 @@ class ListNode extends Node {
}, this.isLoading()); */
}
addItem(item, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in item) {
if (item[k] === '') {
Object.assign(item, {
[k]: null,
});
}
}
const id = (0, uuid_1.generateNewId)();
(0, assert_1.assert)(!this.updates[id]);
this.updates[id] = {
@ -530,6 +538,14 @@ class ListNode extends Node {
* @param afterExecute
*/
updateItem(data, id, action, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
// assert(Object.keys(this.children).length === 0, `更新子结点应该落在相应的component上`);
if (this.children && this.children[id]) {
// 实际中有这样的case出现当使用actionButton时。先这样处理。by Xc 20230214
@ -940,6 +956,14 @@ class SingleNode extends Node {
create(data, beforeExecute, afterExecute) {
const id = (0, uuid_1.generateNewId)();
(0, assert_1.assert)(!this.id && !this.dirty, 'create前要保证singleNode为空');
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
this.operation = {
operation: {
id: (0, uuid_1.generateNewId)(),
@ -952,6 +976,14 @@ class SingleNode extends Node {
this.setDirty();
}
update(data, action, beforeExecute, afterExecute) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
if (!this.operation) {
if (this.id) {
const operation = {

View File

@ -22,7 +22,7 @@ import { InitializeOptions } from './types/Initialize';
*/
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, backendContextBuilder: (contextStr?: string) => (store: DebugStore<ED, Cxt>) => Promise<Cxt>, aspectDict: AD, triggers: Array<Trigger<ED, keyof ED, Cxt>>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, watchers: Array<Watcher<ED, keyof ED, Cxt>>, timers: Array<Timer<ED, Cxt>>, startRoutines: Array<Routine<ED, Cxt>>, initialData: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
}, option: InitializeOptions<ED>): {
}, option: InitializeOptions<ED, Cxt>): {
features: {
cache: import(".").Cache<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;
relationAuth: import("./features/relationAuth").RelationAuth<ED, Cxt, FrontCxt, CommonAspectDict<ED, Cxt> & AD>;

View File

@ -19,7 +19,7 @@ import { InitializeOptions } from './types/Initialize';
* @param actionDict
* @returns
*/
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, connector: Connector<ED, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED>): {
export declare function initialize<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends Record<string, Aspect<ED, Cxt>>>(storageSchema: StorageSchema<ED>, frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt, connector: Connector<ED, FrontCxt>, checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>, option: InitializeOptions<ED, Cxt>): {
features: {
location: import("./features/location").Location;
environment: import("./features/environment").Environment;

View File

@ -1,14 +1,15 @@
import { AsyncContext } from 'oak-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { ActionDictOfEntityDict, ColorDict, Importation, Exportation } from 'oak-domain/lib/types';
import { AuthCascadePath, AuthDeduceRelationMap, EntityDict } from 'oak-domain/lib/types/Entity';
export type InitializeOptions<ED extends EntityDict & BaseEntityDict> = {
export type InitializeOptions<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
actionDict: ActionDictOfEntityDict<ED>;
actionCascadePathGraph: AuthCascadePath<ED>[];
relationCascadePathGraph: AuthCascadePath<ED>[];
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
colorDict: ColorDict<ED>;
importations?: Importation<ED, keyof ED, any>[];
exportations?: Exportation<ED, keyof ED, any>[];
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
createFreeEntities?: (keyof ED)[];
updateFreeEntities?: (keyof ED)[];

View File

@ -131,8 +131,10 @@ function initializeWatchers<ED extends EntityDict & BaseEntityDict, Cxt extends
blockTrigger: true,
});
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
if (rows.length > 0) {
const result = await fn(context, rows);
console.log(`执行了watcher【${w.name}】,结果是:`, result);
}
}
await context.commit();
}

View File

@ -619,6 +619,14 @@ class ListNode<
beforeExecute?: () => Promise<void>,
afterExecute?: () => Promise<void>
) {
// 如果数据键值是一个空字符串则更新成null
for (const k in item) {
if (item[k] === '') {
Object.assign(item, {
[k]: null,
});
}
}
const id = generateNewId();
assert(!this.updates[id]);
this.updates[id] = {
@ -691,6 +699,14 @@ class ListNode<
beforeExecute?: () => Promise<void>,
afterExecute?: () => Promise<void>
) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
// assert(Object.keys(this.children).length === 0, `更新子结点应该落在相应的component上`);
if (this.children && this.children[id]) {
// 实际中有这样的case出现当使用actionButton时。先这样处理。by Xc 20230214
@ -1188,6 +1204,14 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
create(data: Partial<Omit<ED[T]['CreateSingle']['data'], 'id'>>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>) {
const id = generateNewId();
assert(!this.id && !this.dirty, 'create前要保证singleNode为空');
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
this.operation = {
operation: {
id: generateNewId(),
@ -1201,6 +1225,14 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
}
update(data: ED[T]['Update']['data'], action?: ED[T]['Action'], beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>) {
// 如果数据键值是一个空字符串则更新成null
for (const k in data) {
if (data[k] === '') {
Object.assign(data, {
[k]: null,
});
}
}
if (!this.operation) {
if (this.id) {
const operation: ED[T]['Update'] = {

View File

@ -55,7 +55,7 @@ export function initialize<
initialData: {
[T in keyof ED]?: Array<ED[T]['OpSchema']>;
},
option: InitializeOptions<ED>
option: InitializeOptions<ED, Cxt>
) {
const { actionCascadePathGraph, actionDict, relationCascadePathGraph, authDeduceRelationMap,
colorDict, importations, exportations, selectFreeEntities, createFreeEntities, updateFreeEntities,

View File

@ -39,7 +39,7 @@ export function initialize<
frontendContextBuilder: () => (store: CacheStore<ED, FrontCxt>) => FrontCxt,
connector: Connector<ED, FrontCxt>,
checkers: Array<Checker<ED, keyof ED, FrontCxt | Cxt>>,
option: InitializeOptions<ED>
option: InitializeOptions<ED, Cxt>
) {
const { actionCascadePathGraph, relationCascadePathGraph, authDeduceRelationMap, actionDict,
selectFreeEntities, createFreeEntities, updateFreeEntities, colorDict, cacheKeepFreshPeriod, cacheSavedEntities } = option;

View File

@ -1,15 +1,16 @@
import { AsyncContext } from 'oak-domain';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { ActionDictOfEntityDict, CascadeRemoveDefDict, ColorDict, Importation, Exportation } from 'oak-domain/lib/types';
import { AuthCascadePath, AuthDeduceRelationMap, EntityDict } from 'oak-domain/lib/types/Entity';
export type InitializeOptions<ED extends EntityDict & BaseEntityDict> = {
export type InitializeOptions<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
actionDict: ActionDictOfEntityDict<ED>;
actionCascadePathGraph: AuthCascadePath<ED>[];
relationCascadePathGraph: AuthCascadePath<ED>[];
authDeduceRelationMap: AuthDeduceRelationMap<ED>;
colorDict: ColorDict<ED>;
importations?: Importation<ED, keyof ED, any>[];
exportations?: Exportation<ED, keyof ED, any>[];
importations?: Importation<ED, keyof ED, any, Cxt>[];
exportations?: Exportation<ED, keyof ED, any, Cxt>[];
selectFreeEntities?: (keyof ED)[];
createFreeEntities?: (keyof ED)[];
updateFreeEntities?: (keyof ED)[];