mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
Merge pull request #9955 from 2betop/feat-crud-quickSave-events
feat: 补充 crud 的快速保存与拖拽顺序保存事件 Close: #9877
This commit is contained in:
commit
5b8b054f03
@ -3928,18 +3928,24 @@ itemAction 里的 onClick 还能通过 `data` 参数拿到当前行的数据,
|
||||
|
||||
当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`${事件参数名}`或`${event.data.[事件参数名]}`来获取事件产生的数据,详细查看[事件动作](../../docs/concepts/event-action)。
|
||||
|
||||
| 事件名称 | 事件参数 | 说明 |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| fetchInited | `responseData` 接口数据返回 <br /> `responseStatus` 接口返回状态 <br /> `responseMsg` 响应消息 | 远程初始化数据接口请求完成时触发 |
|
||||
| selectedChange | `selectedItems: item[]` 已选择行<br/>`unSelectedItems: item[]` 未选择行 | 手动选择表格项时触发 |
|
||||
| columnSort | `orderBy: string` 列排序列名<br/>`orderDir: string` 列排序值 | 点击列排序时触发 |
|
||||
| columnFilter | `filterName: string` 列筛选列名<br/>`filterValue: string \| undefined` 列筛选值 | 点击列筛选时触发,点击重置后事件参数`filterValue`为`undefined` |
|
||||
| columnSearch | `searchName: string` 列搜索列名<br/>`searchValue: object` 列搜索数据 | 点击列搜索时触发 |
|
||||
| orderChange | `movedItems: item[]` 已排序数据 | 手动拖拽行排序时触发 |
|
||||
| columnToggled | `columns: item[]` 当前显示的列配置数据 | 点击自定义列时触发 |
|
||||
| rowClick | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 点击整行时触发 |
|
||||
| rowMouseEnter | `item: object` 行移入数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 移入整行时触发 |
|
||||
| rowMouseLeave | `item: object` 行移出数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 移出整行时触发 |
|
||||
| 事件名称 | 事件参数 | 说明 |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
||||
| fetchInited | `responseData` 接口数据返回 <br /> `responseStatus` 接口返回状态 <br /> `responseMsg` 响应消息 | 远程初始化数据接口请求完成时触发 |
|
||||
| quickSaveSucc | `result` 接口数据返回 <br /> `rows: object[]` 修改了的行集合 <br /> `rowsDiff: object[]` 与 rows 不同的地方时,对象中只有修改的部分和主键字段 <br /> `indexes: Array<string>` 修改的行索引,如果是树形模式,下标是字符串路劲如 `0.1` <br /> `rowsOrigin: object[]` 原始数据 | 快速编辑完后保存成功触发 |
|
||||
| quickSaveFail | `error` 错误原因 | 快速编辑完后保存失败 |
|
||||
| quickSaveItemSucc | `result` 接口数据返回 <br /> `item: object` 当亲修改的那行数据 <br /> `modified:object` 质只包含修改的部分 <br /> `origin: object` 原始数据 | 快速编辑单条保存成功后触发 |
|
||||
| quickSaveItemFail | `error` 错误原因 | 快速编辑单条保存失败后触发 |
|
||||
| saveOrderSucc | `result` 接口数据返回 <br /> `其他` 请参考 [拖拽排序](#拖拽排序) 章节说明 | 拖拽排序保存成功后触发 |
|
||||
| saveOrderFail | `error` 错误原因 | 拖拽排序保存失败后触发 |
|
||||
| selectedChange | `selectedItems: item[]` 已选择行<br/>`unSelectedItems: item[]` 未选择行 | 手动选择表格项时触发 |
|
||||
| columnSort | `orderBy: string` 列排序列名<br/>`orderDir: string` 列排序值 | 点击列排序时触发 |
|
||||
| columnFilter | `filterName: string` 列筛选列名<br/>`filterValue: string \| undefined` 列筛选值 | 点击列筛选时触发,点击重置后事件参数`filterValue`为`undefined` |
|
||||
| columnSearch | `searchName: string` 列搜索列名<br/>`searchValue: object` 列搜索数据 | 点击列搜索时触发 |
|
||||
| orderChange | `movedItems: item[]` 已排序数据 | 手动拖拽行排序时触发 |
|
||||
| columnToggled | `columns: item[]` 当前显示的列配置数据 | 点击自定义列时触发 |
|
||||
| rowClick | `item: object` 行点击数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 点击整行时触发 |
|
||||
| rowMouseEnter | `item: object` 行移入数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 移入整行时触发 |
|
||||
| rowMouseLeave | `item: object` 行移出数据<br/>`index: number` 行索引 <br />`indexPath: string` 行索引路径 | 移出整行时触发 |
|
||||
|
||||
### selectedChange
|
||||
|
||||
|
@ -49,6 +49,11 @@ interface MatchFunc {
|
||||
|
||||
class ServerError extends Error {
|
||||
type = 'ServerError';
|
||||
readonly response: any;
|
||||
constructor(msg: string, response?: any) {
|
||||
super(msg);
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
export const CRUDStore = ServiceStore.named('CRUDStore')
|
||||
@ -595,7 +600,7 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
throw new ServerError(self.msg);
|
||||
throw new ServerError(self.msg, json);
|
||||
} else {
|
||||
self.updateMessage(
|
||||
(api as ApiObject)?.messages?.success ??
|
||||
@ -615,11 +620,17 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
return json.data;
|
||||
// 补一个空对象是为了区别于被取消的请求
|
||||
// 请求被取消时会返回 undefined
|
||||
return json.data || {};
|
||||
} catch (e) {
|
||||
if (!isAlive(self) || self.disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.markSaving(false);
|
||||
|
||||
if (!isAlive(self) || self.disposed) {
|
||||
if (getEnv(self).isCancel(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1465,7 +1465,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
primaryField,
|
||||
env,
|
||||
messages,
|
||||
reload
|
||||
reload,
|
||||
dispatchEvent
|
||||
} = this.props;
|
||||
|
||||
if (Array.isArray(rows)) {
|
||||
@ -1491,18 +1492,41 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
data.unModifiedItems = unModifiedItems;
|
||||
}
|
||||
|
||||
store
|
||||
return store
|
||||
.saveRemote(quickSaveApi, data, {
|
||||
successMessage: messages && messages.saveFailed,
|
||||
errorMessage: messages && messages.saveSuccess
|
||||
})
|
||||
.then(() => {
|
||||
.then(async result => {
|
||||
// 如果请求 cancel 了,会来到这里
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
const event = await dispatchEvent?.(
|
||||
'quickSaveSucc',
|
||||
extendObject(data, {
|
||||
result: result
|
||||
})
|
||||
);
|
||||
|
||||
if (event?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
const finalReload = options?.reload ?? reload;
|
||||
finalReload
|
||||
return finalReload
|
||||
? this.reloadTarget(filterTarget(finalReload, data), data)
|
||||
: this.search(undefined, undefined, true, true);
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch(async err => {
|
||||
await dispatchEvent?.(
|
||||
'quickSaveFail',
|
||||
createObject(this.props.data, {
|
||||
error: err
|
||||
})
|
||||
);
|
||||
});
|
||||
} else {
|
||||
if (!isEffectiveApi(quickSaveItemApi)) {
|
||||
env && env.alert('CRUD quickSaveItemApi is required!');
|
||||
@ -1516,23 +1540,52 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
});
|
||||
|
||||
const sendData = createObject(data, rows);
|
||||
store
|
||||
return store
|
||||
.saveRemote(quickSaveItemApi, sendData)
|
||||
.then(() => {
|
||||
.then(async (result: any) => {
|
||||
// 如果请求 cancel 了,会来到这里
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const event = await dispatchEvent?.(
|
||||
'quickSaveItemSucc',
|
||||
extendObject(data, {
|
||||
result: result
|
||||
})
|
||||
);
|
||||
|
||||
if (event?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
const finalReload = options?.reload ?? reload;
|
||||
finalReload
|
||||
return finalReload
|
||||
? this.reloadTarget(filterTarget(finalReload, data), data)
|
||||
: this.search(undefined, undefined, true, true);
|
||||
})
|
||||
.catch(() => {
|
||||
.catch(async err => {
|
||||
options?.resetOnFailed && this.control.reset();
|
||||
|
||||
await dispatchEvent?.(
|
||||
'quickSaveItemFail',
|
||||
createObject(this.props.data, {
|
||||
error: err
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleSaveOrder(moved: Array<object>, rows: Array<object>) {
|
||||
const {store, saveOrderApi, orderField, primaryField, env, reload} =
|
||||
this.props;
|
||||
const {
|
||||
store,
|
||||
saveOrderApi,
|
||||
orderField,
|
||||
primaryField,
|
||||
env,
|
||||
reload,
|
||||
dispatchEvent
|
||||
} = this.props;
|
||||
|
||||
if (!saveOrderApi) {
|
||||
env && env.alert('CRUD saveOrderApi is required!');
|
||||
@ -1632,14 +1685,38 @@ export default class CRUD extends React.Component<CRUDProps, any> {
|
||||
));
|
||||
}
|
||||
|
||||
isEffectiveApi(saveOrderApi, model) &&
|
||||
return (
|
||||
isEffectiveApi(saveOrderApi, model) &&
|
||||
store
|
||||
.saveRemote(saveOrderApi, model)
|
||||
.then(() => {
|
||||
.then(async result => {
|
||||
// 如果请求 cancel 了,会来到这里
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const event = await dispatchEvent?.(
|
||||
'saveOrderSucc',
|
||||
extendObject(model, {
|
||||
result: result
|
||||
})
|
||||
);
|
||||
|
||||
if (event?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
reload && this.reloadTarget(filterTarget(reload, model), model);
|
||||
this.search(undefined, undefined, true, true);
|
||||
})
|
||||
.catch(() => {});
|
||||
.catch(async err => {
|
||||
await dispatchEvent?.(
|
||||
'saveOrderFail',
|
||||
createObject(this.props.data, {
|
||||
error: err
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
handleSelect(items: Array<any>, unSelectedItems: Array<any>) {
|
||||
|
Loading…
Reference in New Issue
Block a user