diff --git a/docs/renderers/CRUD.md b/docs/renderers/CRUD.md index 7e79ed0a5..607eae69d 100644 --- a/docs/renderers/CRUD.md +++ b/docs/renderers/CRUD.md @@ -4,50 +4,50 @@ CRUD 支持三种模式:`table`、`cards`、`list`,默认为 `table`。 -| 属性名 | 类型 | 默认值 | 说明 | -| ------------------------------ | ------------------------------ | ------------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| type | `string` | | `type` 指定为 CRUD 渲染器 | -| mode | `string` | `"table"` | `"table" 、 "cards" 或者 "list"` | -| title | `string` | `""` | 可设置成空,当设置成空时,没有标题栏 | -| className | `string` | | 表格外层 Dom 的类名 | -| [api](#api) | [Api](./Types.md#Api) | | CRUD 用来获取列表数据的 api。 | -| loadDataOnce | `boolean` | | 是否一次性加载所有数据(前端分页) | -| source | `string` | | 数据映射接口返回某字段的值,不设置会默认把接口返回的`items`或者`rows`填充进`mode`区域 | -| filter | [Form](./Form/Form.md) | | 设置过滤器,当该表单提交后,会把数据带给当前 `mode` 刷新列表。 | -| filterTogglable | `boolean` | `false` | 是否可显隐过滤器 | -| filterDefaultVisible | `boolean` | `true` | 设置过滤器默认是否可见。 | -| initFetch | `boolean` | `true` | 是否初始化的时候拉取数据, 只针对有 filter 的情况, 没有 filter 初始都会拉取数据 | -| interval | `number` | `3000` | 刷新时间(最低 3000) | -| silentPolling | `boolean` | `false` | 配置刷新时是否隐藏加载动画 | -| stopAutoRefreshWhen | `string` | `""` | 通过[表达式](./Types.md#表达式)来配置停止刷新的条件 | -| stopAutoRefreshWhenModalIsOpen | `boolean` | `false` | 当有弹框时关闭自动刷新,关闭弹框又恢复 | -| syncLocation | `boolean` | `true` | 是否将过滤条件的参数同步到地址栏 | -| draggable | `boolean` | `false` | 是否可通过拖拽排序 | -| itemDraggableOn | `boolean` | | 用[表达式](./Types.md#表达式)来配置是否可拖拽排序 | -| [saveOrderApi](#saveOrderApi) | [Api](./Types.md#Api) | | 保存排序的 api。 | -| [quickSaveApi](#quickSaveApi) | [Api](./Types.md#Api) | | 快速编辑后用来批量保存的 API。 | -| [quickSaveItemApi](#quickSaveItemApi) | [Api](./Types.md#Api) | | 快速编辑配置成及时保存时使用的 API。 | -| bulkActions | Array Of [Action](./Action.md) | | 批量操作列表,配置后,表格可进行选中操作。 | -| defaultChecked | `boolean` | `false` | 当可批量操作时,默认是否全部勾选。 | -| messages | `Object` | | 覆盖消息提示,如果不指定,将采用 api 返回的 message | -| messages.fetchFailed | `string` | | 获取失败时提示 | -| messages.saveOrderFailed | `string` | | 保存顺序失败提示 | -| messages.saveOrderSuccess | `string` | | 保存顺序成功提示 | -| messages.quickSaveFailed | `string` | | 快速保存失败提示 | -| messages.quickSaveSuccess | `string` | | 快速保存成功提示 | -| primaryField | `string` | `"id"` | 设置 ID 字段名。 | -| defaultParams | `Object` | | 设置默认 filter 默认参数,会在查询的时候一起发给后端 | -| pageField | `string` | `"page"` | 设置分页页码字段名。 | -| perPageField | `string` | `"perPage"` | 设置分页一页显示的多少条数据的字段名。注意:最好与 defaultParams 一起使用,请看下面例子。 | -| perPageAvailable | `Array` | `[5, 10, 20, 50, 100]` | 设置一页显示多少条数据下拉框可选条数。 | -| orderField | `string` | | 设置用来确定位置的字段名,设置后新的顺序将被赋值到该字段中。 | -| hideQuickSaveBtn | `boolean` | `false` | 隐藏顶部快速保存提示 | -| autoJumpToTopOnPagerChange | `boolean` | `false` | 当切分页的时候,是否自动跳顶部。 | -| syncResponse2Query | `boolean` | `true` | 将返回数据同步到过滤器上。 | -| keepItemSelectionOnPageChange | `boolean` | `true` | 保留条目选择,默认分页、搜素后,用户选择条目会被清空,开启此选项后会保留用户选择,可以实现跨页面批量操作。 | -| labelTpl | `string` | | 单条描述模板,`keepItemSelectionOnPageChange`设置为`true`后会把所有已选择条目列出来,此选项可以用来定制条目展示文案。 | -| headerToolbar | Array | `['bulkActions', 'pagination']` | 顶部工具栏配置 | -| footerToolbar | Array | `['statistics', 'pagination']` | 顶部工具栏配置 | +| 属性名 | 类型 | 默认值 | 说明 | +|---------------------------------------|--------------------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| type | `string` | | `type` 指定为 CRUD 渲染器 | +| mode | `string` | `"table"` | `"table" 、 "cards" 或者 "list"` | +| title | `string` | `""` | 可设置成空,当设置成空时,没有标题栏 | +| className | `string` | | 表格外层 Dom 的类名 | +| [api](#api) | [Api](./Types.md#Api) | | CRUD 用来获取列表数据的 api。 | +| loadDataOnce | `boolean` | | 是否一次性加载所有数据(前端分页) | +| source | `string` | | 数据映射接口返回某字段的值,不设置会默认把接口返回的`items`或者`rows`填充进`mode`区域 | +| filter | [Form](./Form/Form.md) | | 设置过滤器,当该表单提交后,会把数据带给当前 `mode` 刷新列表。 | +| filterTogglable | `boolean` | `false` | 是否可显隐过滤器 | +| filterDefaultVisible | `boolean` | `true` | 设置过滤器默认是否可见。 | +| initFetch | `boolean` | `true` | 是否初始化的时候拉取数据, 只针对有 filter 的情况, 没有 filter 初始都会拉取数据 | +| interval | `number` | `3000` | 刷新时间(最低 3000) | +| silentPolling | `boolean` | `false` | 配置刷新时是否隐藏加载动画 | +| stopAutoRefreshWhen | `string` | `""` | 通过[表达式](./Types.md#表达式)来配置停止刷新的条件 | +| stopAutoRefreshWhenModalIsOpen | `boolean` | `false` | 当有弹框时关闭自动刷新,关闭弹框又恢复 | +| syncLocation | `boolean` | `true` | 是否将过滤条件的参数同步到地址栏 | +| draggable | `boolean` | `false` | 是否可通过拖拽排序 | +| itemDraggableOn | `boolean` | | 用[表达式](./Types.md#表达式)来配置是否可拖拽排序 | +| [saveOrderApi](#saveOrderApi) | [Api](./Types.md#Api) | | 保存排序的 api。 | +| [quickSaveApi](#quickSaveApi) | [Api](./Types.md#Api) | | 快速编辑后用来批量保存的 API。 | +| [quickSaveItemApi](#quickSaveItemApi) | [Api](./Types.md#Api) | | 快速编辑配置成及时保存时使用的 API。 | +| bulkActions | Array Of [Action](./Action.md) | | 批量操作列表,配置后,表格可进行选中操作。 | +| defaultChecked | `boolean` | `false` | 当可批量操作时,默认是否全部勾选。 | +| messages | `Object` | | 覆盖消息提示,如果不指定,将采用 api 返回的 message | +| messages.fetchFailed | `string` | | 获取失败时提示 | +| messages.saveOrderFailed | `string` | | 保存顺序失败提示 | +| messages.saveOrderSuccess | `string` | | 保存顺序成功提示 | +| messages.quickSaveFailed | `string` | | 快速保存失败提示 | +| messages.quickSaveSuccess | `string` | | 快速保存成功提示 | +| primaryField | `string` | `"id"` | 设置 ID 字段名。 | +| defaultParams | `Object` | | 设置默认 filter 默认参数,会在查询的时候一起发给后端 | +| pageField | `string` | `"page"` | 设置分页页码字段名。 | +| perPageField | `string` | `"perPage"` | 设置分页一页显示的多少条数据的字段名。注意:最好与 defaultParams 一起使用,请看下面例子。 | +| perPageAvailable | `Array` | `[5, 10, 20, 50, 100]` | 设置一页显示多少条数据下拉框可选条数。 | +| orderField | `string` | | 设置用来确定位置的字段名,设置后新的顺序将被赋值到该字段中。 | +| hideQuickSaveBtn | `boolean` | `false` | 隐藏顶部快速保存提示 | +| autoJumpToTopOnPagerChange | `boolean` | `false` | 当切分页的时候,是否自动跳顶部。 | +| syncResponse2Query | `boolean` | `true` | 将返回数据同步到过滤器上。 | +| keepItemSelectionOnPageChange | `boolean` | `true` | 保留条目选择,默认分页、搜素后,用户选择条目会被清空,开启此选项后会保留用户选择,可以实现跨页面批量操作。 | +| labelTpl | `string` | | 单条描述模板,`keepItemSelectionOnPageChange`设置为`true`后会把所有已选择条目列出来,此选项可以用来定制条目展示文案。 | +| headerToolbar | Array | `['bulkActions', 'pagination']` | 顶部工具栏配置 | +| footerToolbar | Array | `['statistics', 'pagination']` | 顶部工具栏配置 | @@ -173,6 +173,7 @@ CRUD 支持三种模式:`table`、`cards`、`list`,默认为 `table`。 * `indexes` `Array` 通过序号的方式告知更新了哪些成员。 * `rows` `Array` 修改过的成员集合,数组对象是在原有数据的基础上更新后的结果。 * `rowsDiff` `Array` 跟 `rows` 不一样的地方是这里只包含本次修改的数据。 +* `rowsOrigin` `Array` 跟 `rows` 不一样的地方是这里是修改前段原始数据。 * `unModifiedItems` `Array` 其他没有修改的成员集合。 默认发送的数据有点多,不过可以通过api的数据映射自己选择需要的部分。 @@ -193,4 +194,64 @@ CRUD 支持三种模式:`table`、`cards`、`list`,默认为 `table`。 **响应:** -响应没有什么特殊要求,只关注 status 状态。 \ No newline at end of file +响应没有什么特殊要求,只关注 status 状态。 + +### 单条操作 + +当操作对象是单条数据时这类操作叫单条操作,比如:编辑、删除、通过、拒绝等等。CRUD 的 table 模式可以在 column 通过放置按钮来完成(其他模式参考 table 模式)。比如编辑就是添加个按钮行为是弹框类型的按钮或者添加一个页面跳转类型的按钮把当前行数据的 id 放在 query 中传过去、删除操作就是配置一个按钮行为是 AJAX 类型的按钮,将数据通过 api 发送给后端完成。 + +CRUD 中不限制有多少个单条操作、添加一个操作对应的添加一个按钮就行了。CRUD 在处理按钮行为的时候会把当前行的完整数据传递过去,如果你的按钮行为是弹出时,还会包含一下信息: + +* `hasNext` `boolean` 当按钮行为是弹框时,还会携带这个数据可以用来判断当前页中是否有下一条数据。 +* `hasPrev` `boolean` 当按钮行为是弹框时,还会携带这个数据可以判断用来当前页中是否有上一条数据。 +* `index` `number` 当按钮行为是弹框时,还会携带这个数据可以用来获取当前行数据在这一页中的位置。 +* `prevIndex` `number` +* `nextIndex` `number` + + +如果你的按钮类型是 AJAX,你也可以限定只发送部分数据比如。 + +```json +{ + "type": "button", + "label": "删除", + "actionType": "ajax", + "api": "delete:/api/xxxx/$id", + "confirmText": "确定要删除?" +} +``` + +上面这个例子就会发送 id 字段了,如果想要全部发送过去同时还想添加点别的字段就这样: + +```json +{ + "type": "button", + "label": "删除", + "actionType": "ajax", + "api": { + "method": "post", + "url": "/api/xxxx/$id", + "data": { + "&": "$$", + "op": "delete" + } + }, + "confirmText": "确定要删除?" +} +``` + +这取决于 api 怎么配置,关于 api 的配置说明请[前往这](./Types.md#api)。 + +### 批量操作 + +当操作对象是多条数据时这类操作叫批量操作、跟单条操作类似,将按钮放在 crud 的 `bulkActions` 中即可, 添加 bulkActions 后列表会自动出现选择框。CRUD 会准备以下数据供按钮行为使用。 + +* `items` `Array` 选中的行数据。 +* `rows` items 的别名,推荐用 items。 +* `unselectedItems` `Array` 没选中的行数据也可获取。 +* `ids` `Array` 前提是行数据中有 id 字段,或者有指定的 `primaryField` 字段。 +* `...第一行所有行数据` 还有第一行的所有行数据也会包含进去。 + +### 快速编辑 + +列信息中可以配置 quickEdit 属性来启动快速编辑功能、开启后当鼠标hover到对应的行时,会出现一个编辑的小图标,点开后弹出表单项完成编辑。保存的结果不会立即发送 api 完成保存,除非你配置了立即保存,当所有的编辑都完成了,可以点击表格顶部的提交按钮,crud 将通过 quickSaveApi 通知后端完成保存。更多信息请看 quickSaveApi 和 quickSaveItemApi 的说明。 \ No newline at end of file diff --git a/docs/renderers/Form/Form.md b/docs/renderers/Form/Form.md index 5f785b520..bbb7d81dd 100644 --- a/docs/renderers/Form/Form.md +++ b/docs/renderers/Form/Form.md @@ -26,49 +26,49 @@ } ``` -| 属性名 | 类型 | 默认值 | 说明 | -| --------------------- | ------------------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| type | `string` | | `"form"` 指定为 Form 渲染器 | -| mode | `string` | `normal` | 表单展示方式,可以是:`normal`、`horizontal` 或者 `inline` | -| horizontal | `Object` | `{"left":"col-sm-2", "right":"col-sm-10", "offset":"col-sm-offset-2"}` | 当 mode 为 `horizontal` 时有用,用来控制 label | -| title | `string` | `"表单"` | Form 的标题 | -| submitText | `String` | `"提交"` | 默认的提交按钮名称,如果设置成空,则可以把默认按钮去掉。 | -| className | `string` | | 外层 Dom 的类名 | -| controls | `Array` of [FormItem](./FormItem.md) | | Form 表单项集合 | -| actions | `Array` of [Action](../Action.md) | | Form 提交按钮,成员为 Action | -| messages | `Object` | | 消息提示覆写,默认消息读取的是 API 返回的消息,但是在此可以覆写它。 | -| messages.fetchSuccess | `string` | | 获取成功时提示 | -| messages.fetchFailed | `string` | | 获取失败时提示 | -| messages.saveFailed | `string` | | 保存成功时提示 | -| messages.saveSuccess | `string` | | 保存失败时提示 | -| wrapWithPanel | `boolean` | `true` | 是否让 Form 用 panel 包起来,设置为 false 后,actions 将无效。 | -| panelClassName | `boolean` | `true` | 是否让 Form 用 panel 包起来,设置为 false 后,actions 将无效。 | -| [api](#api) | [Api](../Types.md#api) | | Form 用来保存数据的 api。 | -| [initApi](#initApi) | [Api](../Types.md#api) | | Form 用来获取初始数据的 api。 | -| interval | `number` | `3000` | 刷新时间(最低 3000) | -| silentPolling | `boolean` | `false` | 配置刷新时是否显示加载动画 | -| stopAutoRefreshWhen | `string` | `""` | 通过[表达式](./Types.md#表达式) 来配置停止刷新的条件 | -| [initAsyncApi](#initAsyncApi) | [Api](../Types.md#api) | | Form 用来获取初始数据的 api,与 initApi 不同的是,会一直轮训请求该接口,直到返回 finished 属性为 true 才 结束。 | -| initFetch | `boolean` | `true` | 设置了 initApi 或者 initAsyncApi 后,默认会开始就发请求,设置为 false 后就不会起始就请求接口 | -| initFetchOn | `string` | | 用表达式来配置 | -| initFinishedField | `string` | `finished` | 设置了 initAsyncApi 后,默认会从返回数据的 data.finished 来判断是否完成,也可以设置成其他的 xxx,就会从 data.xxx 中获取 | -| initCheckInterval | `number` | `3000` | 设置了 initAsyncApi 以后,默认拉取的时间间隔 | -| schemaApi | [Api](../Types.md#api) | | `已不支持`,请改用 controls 里面放置 Service 渲染器实现 | -| [asyncApi](#asyncApi) | [Api](../Types.md#api) | | 设置此属性后,表单提交发送保存接口后,还会继续轮训请求该接口,直到返回 `finished` 属性为 `true` 才 结束。 | -| checkInterval | `number` | 3000 | 轮训请求的时间间隔,默认为 3 秒。设置 `asyncApi` 才有效 | -| finishedField | `string` | `"finished"` | 如果决定结束的字段名不是 `finished` 请设置此属性,比如 `is_success` | -| submitOnChange | `boolean` | `false` | 表单修改即提交 | -| submitOnInit | `boolean` | `false` | 初始就提交一次 | -| resetAfterSubmit | `boolean` | `false` | 提交后是否重置表单 | -| primaryField | `string` | `"id"` | 设置主键 id, 当设置后,检测表单是否完成时(asyncApi),只会携带此数据。 | -| target | `string` | | 默认表单提交自己会通过发送 api 保存数据,但是也可以设定另外一个 form 的 name 值,或者另外一个 `CRUD` 模型的 name 值。 如果 target 目标是一个 `Form` ,则目标 `Form` 会重新触发 `initApi`,api 可以拿到当前 form 数据。如果目标是一个 `CRUD` 模型,则目标模型会重新触发搜索,参数为当前 Form 数据。当目标是 `window` 时,会把当前表单的数据附带到页面地址上。 | -| redirect | `string` | | 设置此属性后,Form 保存成功后,自动跳转到指定页面。支持相对地址,和绝对地址(相对于组内的)。 | -| reload | `string` | | 操作完后刷新目标对象。请填写目标组件设置的 name 值,如果填写为 `window` 则让当前页面整体刷新。 | -| autoFocus | `boolean` | `false` | 是否自动聚焦。 | -| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表单项上 | -| persistData | `boolean` | `true` | 指定表单是否开启本地缓存 | -| clearPersistDataAfterSubmit | `boolean` | `true` | 指定表单提交成功后是否清除本地缓存 | -| name | `string` | | 设置一个名字后,方便其他组件与其通信 | +| 属性名 | 类型 | 默认值 | 说明 | +|-------------------------------|--------------------------------------|------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| type | `string` | | `"form"` 指定为 Form 渲染器 | +| mode | `string` | `normal` | 表单展示方式,可以是:`normal`、`horizontal` 或者 `inline` | +| horizontal | `Object` | `{"left":"col-sm-2", "right":"col-sm-10", "offset":"col-sm-offset-2"}` | 当 mode 为 `horizontal` 时有用,用来控制 label | +| title | `string` | `"表单"` | Form 的标题 | +| submitText | `String` | `"提交"` | 默认的提交按钮名称,如果设置成空,则可以把默认按钮去掉。 | +| className | `string` | | 外层 Dom 的类名 | +| controls | `Array` of [FormItem](./FormItem.md) | | Form 表单项集合 | +| actions | `Array` of [Action](../Action.md) | | Form 提交按钮,成员为 Action | +| messages | `Object` | | 消息提示覆写,默认消息读取的是 API 返回的消息,但是在此可以覆写它。 | +| messages.fetchSuccess | `string` | | 获取成功时提示 | +| messages.fetchFailed | `string` | | 获取失败时提示 | +| messages.saveFailed | `string` | | 保存成功时提示 | +| messages.saveSuccess | `string` | | 保存失败时提示 | +| wrapWithPanel | `boolean` | `true` | 是否让 Form 用 panel 包起来,设置为 false 后,actions 将无效。 | +| panelClassName | `boolean` | `true` | 是否让 Form 用 panel 包起来,设置为 false 后,actions 将无效。 | +| [api](#api) | [Api](../Types.md#api) | | Form 用来保存数据的 api。 | +| [initApi](#initApi) | [Api](../Types.md#api) | | Form 用来获取初始数据的 api。 | +| interval | `number` | `3000` | 刷新时间(最低 3000) | +| silentPolling | `boolean` | `false` | 配置刷新时是否显示加载动画 | +| stopAutoRefreshWhen | `string` | `""` | 通过[表达式](./Types.md#表达式) 来配置停止刷新的条件 | +| [initAsyncApi](#initAsyncApi) | [Api](../Types.md#api) | | Form 用来获取初始数据的 api,与 initApi 不同的是,会一直轮训请求该接口,直到返回 finished 属性为 true 才 结束。 | +| initFetch | `boolean` | `true` | 设置了 initApi 或者 initAsyncApi 后,默认会开始就发请求,设置为 false 后就不会起始就请求接口 | +| initFetchOn | `string` | | 用表达式来配置 | +| initFinishedField | `string` | `finished` | 设置了 initAsyncApi 后,默认会从返回数据的 data.finished 来判断是否完成,也可以设置成其他的 xxx,就会从 data.xxx 中获取 | +| initCheckInterval | `number` | `3000` | 设置了 initAsyncApi 以后,默认拉取的时间间隔 | +| schemaApi | [Api](../Types.md#api) | | `已不支持`,请改用 controls 里面放置 Service 渲染器实现 | +| [asyncApi](#asyncApi) | [Api](../Types.md#api) | | 设置此属性后,表单提交发送保存接口后,还会继续轮训请求该接口,直到返回 `finished` 属性为 `true` 才 结束。 | +| checkInterval | `number` | 3000 | 轮训请求的时间间隔,默认为 3 秒。设置 `asyncApi` 才有效 | +| finishedField | `string` | `"finished"` | 如果决定结束的字段名不是 `finished` 请设置此属性,比如 `is_success` | +| submitOnChange | `boolean` | `false` | 表单修改即提交 | +| submitOnInit | `boolean` | `false` | 初始就提交一次 | +| resetAfterSubmit | `boolean` | `false` | 提交后是否重置表单 | +| primaryField | `string` | `"id"` | 设置主键 id, 当设置后,检测表单是否完成时(asyncApi),只会携带此数据。 | +| target | `string` | | 默认表单提交自己会通过发送 api 保存数据,但是也可以设定另外一个 form 的 name 值,或者另外一个 `CRUD` 模型的 name 值。 如果 target 目标是一个 `Form` ,则目标 `Form` 会重新触发 `initApi`,api 可以拿到当前 form 数据。如果目标是一个 `CRUD` 模型,则目标模型会重新触发搜索,参数为当前 Form 数据。当目标是 `window` 时,会把当前表单的数据附带到页面地址上。 | +| redirect | `string` | | 设置此属性后,Form 保存成功后,自动跳转到指定页面。支持相对地址,和绝对地址(相对于组内的)。 | +| reload | `string` | | 操作完后刷新目标对象。请填写目标组件设置的 name 值,如果填写为 `window` 则让当前页面整体刷新。 | +| autoFocus | `boolean` | `false` | 是否自动聚焦。 | +| canAccessSuperData | `boolean` | `true` | 指定是否可以自动获取上层的数据并映射到表单项上 | +| persistData | `boolean` | `true` | 指定表单是否开启本地缓存 | +| clearPersistDataAfterSubmit | `boolean` | `true` | 指定表单提交成功后是否清除本地缓存 | +| name | `string` | | 设置一个名字后,方便其他组件与其通信 | 表单项都是通过 controls 设置的,类型是数组,成员主要是[FormItem](./FormItem.md),默认一行一个(当然 form 是 inline 模式时例外),如果想一行多个,可以将多个[FormItem](./FormItem.md)放在一个 [Group](./Group.md) 里面。 @@ -236,7 +236,27 @@ **发送** - 默认为 `POST` 方式,会将所有表单项整理成一个对象发送过过去。 + 默认为 `POST` 方式,会将所有表单项整理成一个对象发送过过去。除此之外你开可以主动的获取以下信息。 + + * `diff` 只会包含diff 结果 + * `prinstine` 原始数据。 + + 如: + + + ```json + { + "api": { + "method": "post", + "url": "/api/xxx/save", + "data": { + "modified": "$$", + "diff": "${diff}", + "origin": "${prinstine}" + } + } + } + ``` **响应** diff --git a/scss/components/form/_form.scss b/scss/components/form/_form.scss index 56f6ac679..6be0970c7 100644 --- a/scss/components/form/_form.scss +++ b/scss/components/form/_form.scss @@ -7,7 +7,7 @@ } &--inline { - > .#{$ns}PlainField { + >.#{$ns}PlainField { display: inline-block; padding-top: $Form-input-paddingY; // padding-bottom: $Form-input-paddingY; @@ -20,8 +20,9 @@ margin-bottom: px2rem(5px); display: inline-block; max-width: 100%; + position: relative; - > span { + >span { position: relative; } } @@ -30,9 +31,8 @@ color: $red; font-size: $fontSizeXs; position: absolute; - left: 100%; - top: px2rem(5px); - margin-left: px2rem(3px); + left: px2rem(-7px); + top: px2rem(4px); line-height: 1; } @@ -60,11 +60,11 @@ .#{$ns}Form-item { margin-bottom: $Form-item-gap; - .#{$ns}Grid-form > &:last-child { + .#{$ns}Grid-form>&:last-child { margin-bottom: 0; } - .#{$ns}Form--inline > &--inline { + .#{$ns}Form--inline>&--inline { margin-bottom: $Form-item-gap/2; margin-right: $Form-item-gap/2; @@ -80,18 +80,18 @@ } &--horizontal { - > .#{$ns}Form-label { + >.#{$ns}Form-label { text-align: $Form--horizontal-label-align; } } &--normal { - > .#{$ns}Form-label { + >.#{$ns}Form-label { display: block; } } - &.is-error > .#{$ns}Form-label { + &.is-error>.#{$ns}Form-label { color: $danger; } } @@ -136,13 +136,13 @@ margin-left: -$Form--horizontal-gutterWidth / 2; margin-right: -$Form--horizontal-gutterWidth / 2; - > * { + >* { padding-left: $Form--horizontal-gutterWidth / 2; padding-right: $Form--horizontal-gutterWidth / 2; } - > .#{$ns}Form-label, - > .#{$ns}Form-value { + >.#{$ns}Form-label, + >.#{$ns}Form-value { flex-basis: 0; flex-grow: 1; max-width: 100%; @@ -157,7 +157,7 @@ flex-basis: unset; } - > .#{$ns}Form-label { + >.#{$ns}Form-label { padding-top: $Form-label-paddingTop; margin-bottom: 0; } @@ -195,7 +195,7 @@ display: inline-block; vertical-align: top; - > .#{$ns}Form-label { + >.#{$ns}Form-label { padding-top: $Form-label-paddingTop; margin-bottom: 0; margin-right: $Form-item-gap/2; @@ -205,19 +205,19 @@ } } - > .#{$ns}Form-value { + >.#{$ns}Form-value { display: inline; - > .#{$ns}Form-control { + >.#{$ns}Form-control { vertical-align: top; display: inline-block; } - > .#{$ns}Form-control.#{$ns}InputGroup { + >.#{$ns}Form-control.#{$ns}InputGroup { display: inline-flex; } - > .#{$ns}TextControl--withAddOn { + >.#{$ns}TextControl--withAddOn { display: inline-flex; } } @@ -232,7 +232,7 @@ margin-right: -$Form-row-gutterWidth / 2; align-items: flex-start; - > * { + >* { padding-left: $Form-row-gutterWidth / 2; padding-right: $Form-row-gutterWidth / 2; } @@ -248,16 +248,16 @@ display: flex; flex-wrap: nowrap; - > .#{$ns}Form-label { + >.#{$ns}Form-label { display: inline-block; vertical-align: top; padding-top: $Form-label-paddingTop; padding-right: $Form-row-gutterWidth; } - > .#{$ns}Form-control { + >.#{$ns}Form-control { flex-basis: 0; flex-grow: 1; } } -} +} \ No newline at end of file diff --git a/src/icons/upload.svg b/src/icons/upload.svg index 1906b4a41..0516398d0 100644 --- a/src/icons/upload.svg +++ b/src/icons/upload.svg @@ -1,6 +1,6 @@ - + diff --git a/src/store/form.ts b/src/store/form.ts index 28acf5764..b48c321eb 100644 --- a/src/store/form.ts +++ b/src/store/form.ts @@ -128,7 +128,7 @@ export const FormStore = ServiceStore.named('FormStore') setVariable(pristine, name, value); self.pristine = pristine; } - + if (!data.__pristine) { Object.defineProperty(data, '__pristine', { value: self.pristine, @@ -286,7 +286,9 @@ export const FormStore = ServiceStore.named('FormStore') createObject( createObject(self.data.__super, { diff: diff, - __diff: diff + __diff: diff, + pristine: self.pristine, + __pristine: self.pristine }), self.data )