mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:58:05 +08:00
Merge pull request #10399 from 2betop/fix-store-sync
fix: 修复 store 数据上下层同步问题
This commit is contained in:
commit
09e564e9e7
@ -298,7 +298,7 @@ export function HocStoreFactory(renderer: {
|
||||
props.store?.storeType === 'ComboStore'
|
||||
? undefined
|
||||
: syncDataFromSuper(
|
||||
{...store.data, ...props.data},
|
||||
{...store.pristineDiff, ...props.data},
|
||||
(props.data as any).__super,
|
||||
(prevProps.data as any).__super,
|
||||
store,
|
||||
|
@ -25,7 +25,8 @@ export const iRendererStore = StoreNode.named('iRendererStore')
|
||||
data: types.optional(types.frozen(), {}),
|
||||
initedAt: 0, // 初始 init 的时刻
|
||||
updatedAt: 0, // 从服务端更新时刻
|
||||
pristine: types.optional(types.frozen(), {}),
|
||||
pristine: types.optional(types.frozen(), {}), // pristine 的数据可能会被表单项的默认值,form 的 initApi 等修改
|
||||
upStreamData: types.optional(types.frozen(), {}), // 最原始的数据,只有由上游同步下来时才更新。用来判断是否变化过
|
||||
action: types.optional(types.frozen(), undefined),
|
||||
dialogOpen: false,
|
||||
dialogData: types.optional(types.frozen(), undefined),
|
||||
@ -39,6 +40,16 @@ export const iRendererStore = StoreNode.named('iRendererStore')
|
||||
|
||||
getPristineValueByName(name: string) {
|
||||
return getVariable(self.pristine, name, false);
|
||||
},
|
||||
|
||||
get pristineDiff() {
|
||||
const data: any = {};
|
||||
Object.keys(self.pristine).forEach(key => {
|
||||
if (self.pristine[key] !== self.upStreamData[key]) {
|
||||
data[key] = self.pristine[key];
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
}))
|
||||
.actions(self => {
|
||||
@ -63,6 +74,7 @@ export const iRendererStore = StoreNode.named('iRendererStore')
|
||||
|
||||
!skipSetPristine && (self.pristine = data);
|
||||
self.data = data;
|
||||
self.upStreamData = data;
|
||||
},
|
||||
|
||||
reset() {
|
||||
|
@ -1784,3 +1784,115 @@ test('23. Nested CRUD change to normal CRUD', async () => {
|
||||
const newSpace = container.querySelectorAll('.cxd-Table-expandSpace');
|
||||
expect(newSpace.length).toEqual(0);
|
||||
});
|
||||
|
||||
// CRUD 列中存在一列 List 组件,List 是带 store 的,crud 的行数据发生切换时,
|
||||
// 如果 list 关联的数组,从有有成员变成 undefined 时,会出现 List 的数据不更新的问题。
|
||||
// 原因是 withStore 里面同步逻辑有问题,保留了原来的 store.data
|
||||
test('25. CRUD Table Cell sync data to store', async () => {
|
||||
const {container} = render(
|
||||
amisRender({
|
||||
type: 'page',
|
||||
id: 'page',
|
||||
data: {
|
||||
source: [
|
||||
{
|
||||
engine: 'Trident',
|
||||
browser: 'Internet Explorer 5.0',
|
||||
platform: 'Win 95+',
|
||||
version: '5',
|
||||
grade: 'C',
|
||||
id: '1-1',
|
||||
list: [{id: '1-1-1', name: '1-1-1'}]
|
||||
},
|
||||
{
|
||||
engine: 'Trident',
|
||||
browser: 'Internet Explorer 5.0',
|
||||
platform: 'Win 95+',
|
||||
version: '5',
|
||||
grade: 'C',
|
||||
id: '5'
|
||||
}
|
||||
]
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'button',
|
||||
label: '切换数据源',
|
||||
onEvent: {
|
||||
click: {
|
||||
actions: [
|
||||
{
|
||||
actionType: 'setValue',
|
||||
componentId: 'page',
|
||||
args: {
|
||||
value: {
|
||||
source: [
|
||||
{
|
||||
engine: 'Trident',
|
||||
browser: 'Internet Explorer 4.0',
|
||||
platform: 'Win 95+',
|
||||
version: '4',
|
||||
grade: 'X',
|
||||
id: '3'
|
||||
},
|
||||
{
|
||||
engine: 'Trident',
|
||||
browser: 'Internet Explorer 4.0',
|
||||
platform: 'Win 95+',
|
||||
version: '4',
|
||||
grade: 'X',
|
||||
id: '4'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'crud',
|
||||
name: 'crud',
|
||||
syncLocation: false,
|
||||
source: '${source}',
|
||||
draggable: true,
|
||||
columns: [
|
||||
{
|
||||
name: 'id',
|
||||
label: 'ID'
|
||||
},
|
||||
{
|
||||
name: 'engine',
|
||||
label: 'Rendering engine'
|
||||
},
|
||||
{
|
||||
name: 'list',
|
||||
label: 'List',
|
||||
type: 'list',
|
||||
source: '${list}',
|
||||
listItem: {
|
||||
title: '${id}-${name}'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
);
|
||||
|
||||
await wait(300);
|
||||
|
||||
const button = container.querySelectorAll('.cxd-Button')[0];
|
||||
|
||||
// 刚开始存在 list 字段,所以是 1
|
||||
const listDoms = container.querySelectorAll('.cxd-ListItem-title');
|
||||
expect(listDoms.length).toEqual(1);
|
||||
|
||||
fireEvent.click(button);
|
||||
await wait(300);
|
||||
|
||||
// 切换后 list 字段是 undefined 了,所以应该不显示了
|
||||
const listDoms2 = container.querySelectorAll('.cxd-ListItem-title');
|
||||
expect(listDoms2.length).toEqual(0);
|
||||
});
|
||||
|
@ -26,6 +26,7 @@ exports[`store:ServiceStore 1`] = `
|
||||
"schema": null,
|
||||
"schemaKey": "",
|
||||
"storeType": "ServiceStore",
|
||||
"upStreamData": {},
|
||||
"updatedAt": 0,
|
||||
}
|
||||
`;
|
||||
@ -57,6 +58,7 @@ exports[`store:ServiceStore fetchInitData failed 1`] = `
|
||||
"schema": null,
|
||||
"schemaKey": "",
|
||||
"storeType": "ServiceStore",
|
||||
"upStreamData": {},
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
@ -84,6 +86,7 @@ exports[`store:ServiceStore fetchInitData failed 1`] = `
|
||||
"schema": null,
|
||||
"schemaKey": "",
|
||||
"storeType": "ServiceStore",
|
||||
"upStreamData": {},
|
||||
"updatedAt": 0,
|
||||
},
|
||||
]
|
||||
@ -116,6 +119,7 @@ exports[`store:ServiceStore fetchInitData success 1`] = `
|
||||
"schema": null,
|
||||
"schemaKey": "",
|
||||
"storeType": "ServiceStore",
|
||||
"upStreamData": {},
|
||||
},
|
||||
{
|
||||
"action": undefined,
|
||||
@ -148,6 +152,7 @@ exports[`store:ServiceStore fetchInitData success 1`] = `
|
||||
"schema": null,
|
||||
"schemaKey": "",
|
||||
"storeType": "ServiceStore",
|
||||
"upStreamData": {},
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
@ -290,10 +290,10 @@ export default class Cards extends React.Component<GridProps, object> {
|
||||
? resolveVariableAndFilter(source, prevProps.data, '| raw')
|
||||
: null;
|
||||
|
||||
if (prev && prev === resolved) {
|
||||
if (prev === resolved) {
|
||||
updateItems = false;
|
||||
} else if (Array.isArray(resolved)) {
|
||||
items = resolved;
|
||||
} else {
|
||||
items = Array.isArray(resolved) ? resolved : [];
|
||||
updateItems = true;
|
||||
}
|
||||
}
|
||||
|
@ -373,10 +373,10 @@ export default class List extends React.Component<ListProps, object> {
|
||||
? resolveVariableAndFilter(source, prevProps.data, '| raw')
|
||||
: null;
|
||||
|
||||
if (prev && prev === resolved) {
|
||||
if (prev === resolved) {
|
||||
updateItems = false;
|
||||
} else if (Array.isArray(resolved)) {
|
||||
items = resolved;
|
||||
} else {
|
||||
items = Array.isArray(resolved) ? resolved : [];
|
||||
updateItems = true;
|
||||
}
|
||||
}
|
||||
|
@ -710,11 +710,11 @@ export default class Table extends React.Component<TableProps, object> {
|
||||
? resolveVariableAndFilter(source, prevProps.data, '| raw')
|
||||
: null;
|
||||
|
||||
if (prev && prev === resolved) {
|
||||
if (prev === resolved) {
|
||||
updateRows = false;
|
||||
} else if (Array.isArray(resolved)) {
|
||||
} else {
|
||||
updateRows = true;
|
||||
rows = resolved;
|
||||
rows = Array.isArray(resolved) ? resolved : [];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user