diff --git a/docs/zh-CN/components/crud.md b/docs/zh-CN/components/crud.md index 461fa7e8a..385d89324 100755 --- a/docs/zh-CN/components/crud.md +++ b/docs/zh-CN/components/crud.md @@ -534,60 +534,85 @@ Cards 模式支持 [Cards](./cards) 中的所有功能。 ## 查询条件表单 -大部分表格展示有对数据进行检索的需求,CRUD 自身支持通过配置`filter`,实现查询条件过滤表单 +大部分表格展示有对数据进行检索的需求,CRUD 自身支持通过配置`filter`,实现查询条件过滤表单。`filter` 配置实际上同 [Form](./form/index) 组件,因此支持绝大部分`form`的功能。 -`filter` 配置实际上同 [Form](./form/index) 组件,因此支持绝大部分`form`的功能。 +在条件搜索区的 `Engine` 输入框中输入任意值查询会发现结果中 `ID` 为 1 - 3 的 `Rendering engine` 列因为返回值中没有对应字段值,被错误填入了与 `filter` 中相同 `name` 的字段值,这是因为表格 Cell 通过[数据链](../../docs/concepts/datascope-and-datachain)获取到了上层数据域 `filter` 中相同字段的数据值。这种情况可以在 CRUD `columns` 对应列配置`"canAccessSuperData": false`禁止访问父级数据域(比如: `Platform`列)。 ```schema: scope="body" { "type": "crud", "name": "crud", "syncLocation": false, - "api": "/api/mock2/sample", - "filter": { + "api": "/api/mock2/crud/table4", + "filter": { + "debug": true, "title": "条件搜索", "body": [ { - "type": "flex", - "justify": "space-between", - "alignItems": "center", - "items": [ + "type": "group", + "body": [ { "type": "input-text", "name": "keywords", + "label": "关键字", + "clearable": true, "placeholder": "通过关键字搜索", "size": "sm" }, { - "type": "button", - "actionType": "drawer", - "icon": "fa fa-plus", - "label": "创建记录", - "target": "crud", - "closeOnOutside": true, - "drawer": { - "title": "创建记录", - "body": { - "type": "form", - "api": "post:/api/mock2/sample", - "body": [ - { - "type": "input-text", - "name": "engine", - "label": "Engine" - }, - { - "type": "input-text", - "name": "browser", - "label": "Browser" - } - ] - } - } + "type": "input-text", + "name": "engine", + "label": "Engine", + "clearable": true, + "size": "sm" + }, + { + "type": "input-text", + "name": "platform", + "label": "Platform", + "clearable": true, + "size": "sm" } ] } - + ], + actions: [ + { + "type": "button", + "actionType": "drawer", + "icon": "fa fa-plus", + "label": "创建记录", + "target": "crud", + "closeOnOutside": true, + "drawer": { + "title": "创建记录", + "body": { + "type": "form", + "api": "post:/api/mock2/sample", + "body": [ + { + "type": "input-text", + "name": "engine", + "label": "Engine" + }, + { + "type": "input-text", + "name": "browser", + "label": "Browser" + } + ] + } + } + }, + { + "type": "reset", + "label": "重置" + }, + { + "type": "submit", + "level": "primary", + "label": "查询" + } ] }, "columns": [ @@ -605,7 +630,8 @@ Cards 模式支持 [Cards](./cards) 中的所有功能。 }, { "name": "platform", - "label": "Platform(s)" + "label": "Platform(s)", + "canAccessSuperData": false }, { "name": "version", diff --git a/mock/cfc/mock/crud/table4.js b/mock/cfc/mock/crud/table4.js new file mode 100644 index 000000000..ad23c2416 --- /dev/null +++ b/mock/cfc/mock/crud/table4.js @@ -0,0 +1,431 @@ +/** 部分列字段没有没回值的CASE */ +module.exports = function (req, res) { + const perPage = 10; + const page = req.query.page || 1; + let items = data.concat(); + + if (req.query.keywords) { + const keywords = req.query.keywords; + items = items.filter(function (item) { + return ~JSON.stringify(item).indexOf(keywords); + }); + } + + const validQueryKey = Object.keys(req.query).filter( + item => item !== 'keywords' && req.query[item] != null + ); + + if (validQueryKey.length > 0) { + items = items.filter(item => + validQueryKey.every(key => !!~req.query[key].indexOf(item[key] || '')) + ); + } + + const ret = { + status: 0, + msg: 'ok', + data: { + count: items.length, + rows: items.concat().splice((page - 1) * perPage, perPage) + } + }; + + res.json(ret); +}; + +const data = [ + { + browser: 'Internet Explorer 4.0', + platform: 'Win 95+', + version: '4', + grade: 'X' + }, + { + browser: 'Internet Explorer 5.0', + platform: 'Win 95+', + version: '5', + grade: 'C' + }, + { + browser: 'Internet Explorer 5.5', + platform: 'Win 95+', + version: '5.5', + grade: 'A' + }, + { + engine: 'Trident', + browser: 'Internet Explorer 6', + version: '6', + grade: 'A' + }, + { + engine: 'Trident', + browser: 'Internet Explorer 7', + version: '7', + grade: 'A' + }, + { + engine: 'Trident', + browser: 'AOL browser (AOL desktop)', + platform: 'Win XP', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Firefox 1.0', + platform: 'Win 98+ / OSX.2+', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Firefox 1.5', + platform: 'Win 98+ / OSX.2+', + version: '1.8' + }, + { + engine: 'Gecko', + browser: 'Firefox 2.0', + platform: 'Win 98+ / OSX.2+', + version: '1.8' + }, + { + engine: 'Gecko', + browser: 'Firefox 3.0', + platform: 'Win 2k+ / OSX.3+', + version: '1.9', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Camino 1.0', + platform: 'OSX.2+', + version: '1.8', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Camino 1.5', + platform: 'OSX.3+', + version: '1.8', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Netscape 7.2', + platform: 'Win 95+ / Mac OS 8.6-9.2', + version: '1.7', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Netscape Browser 8', + platform: 'Win 98SE+', + version: '1.7', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Netscape Navigator 9', + platform: 'Win 98+ / OSX.2+', + version: '1.8', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.0', + platform: 'Win 95+ / OSX.1+', + version: '1', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.1', + platform: 'Win 95+ / OSX.1+', + version: '1.1', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.2', + platform: 'Win 95+ / OSX.1+', + version: '1.2', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.3', + platform: 'Win 95+ / OSX.1+', + version: '1.3', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.4', + platform: 'Win 95+ / OSX.1+', + version: '1.4', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.5', + platform: 'Win 95+ / OSX.1+', + version: '1.5', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.6', + platform: 'Win 95+ / OSX.1+', + version: '1.6', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.7', + platform: 'Win 98+ / OSX.1+', + version: '1.7', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Mozilla 1.8', + platform: 'Win 98+ / OSX.1+', + version: '1.8', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Seamonkey 1.1', + platform: 'Win 98+ / OSX.2+', + version: '1.8', + grade: 'A' + }, + { + engine: 'Gecko', + browser: 'Epiphany 2.20', + platform: 'Gnome', + version: '1.8', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'Safari 1.2', + platform: 'OSX.3', + version: '125.5', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'Safari 1.3', + platform: 'OSX.3', + version: '312.8', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'Safari 2.0', + platform: 'OSX.4+', + version: '419.3', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'Safari 3.0', + platform: 'OSX.4+', + version: '522.1', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'OmniWeb 5.5', + platform: 'OSX.4+', + version: '420', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'iPod Touch / iPhone', + platform: 'iPod', + version: '420.1', + grade: 'A' + }, + { + engine: 'Webkit', + browser: 'S60', + platform: 'S60', + version: '413', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 7.0', + platform: 'Win 95+ / OSX.1+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 7.5', + platform: 'Win 95+ / OSX.2+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 8.0', + platform: 'Win 95+ / OSX.2+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 8.5', + platform: 'Win 95+ / OSX.2+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 9.0', + platform: 'Win 95+ / OSX.3+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 9.2', + platform: 'Win 88+ / OSX.3+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera 9.5', + platform: 'Win 88+ / OSX.3+', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Opera for Wii', + platform: 'Wii', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Nokia N800', + platform: 'N800', + version: '-', + grade: 'A' + }, + { + engine: 'Presto', + browser: 'Nintendo DS browser', + platform: 'Nintendo DS', + version: '8.5', + grade: 'C' + }, + { + engine: 'KHTML', + browser: 'Konqureror 3.1', + platform: 'KDE 3.1', + version: '3.1', + grade: 'C' + }, + { + engine: 'KHTML', + browser: 'Konqureror 3.3', + platform: 'KDE 3.3', + version: '3.3', + grade: 'A' + }, + { + engine: 'KHTML', + browser: 'Konqureror 3.5', + platform: 'KDE 3.5', + version: '3.5', + grade: 'A' + }, + { + engine: 'Tasman', + browser: 'Internet Explorer 4.5', + platform: 'Mac OS 8-9', + version: '-', + grade: 'X' + }, + { + engine: 'Tasman', + browser: 'Internet Explorer 5.1', + platform: 'Mac OS 7.6-9', + version: '1', + grade: 'C' + }, + { + engine: 'Tasman', + browser: 'Internet Explorer 5.2', + platform: 'Mac OS 8-X', + version: '1', + grade: 'C' + }, + { + engine: 'Misc', + browser: 'NetFront 3.1', + platform: 'Embedded devices', + version: '-', + grade: 'C' + }, + { + engine: 'Misc', + browser: 'NetFront 3.4', + platform: 'Embedded devices', + version: '-', + grade: 'A' + }, + { + engine: 'Misc', + browser: 'Dillo 0.8', + platform: 'Embedded devices', + version: '-', + grade: 'X' + }, + { + engine: 'Misc', + browser: 'Links', + platform: 'Text only', + version: '-', + grade: 'X' + }, + { + engine: 'Misc', + browser: 'Lynx', + platform: 'Text only', + version: '-', + grade: 'X' + }, + { + engine: 'Misc', + browser: 'IE Mobile', + platform: 'Windows Mobile 6', + version: '-', + grade: 'C' + }, + { + engine: 'Misc', + browser: 'PSP browser', + platform: 'PSP', + version: '-', + grade: 'C' + }, + { + engine: 'Other browsers', + browser: 'All others', + platform: '-', + version: '-', + grade: 'U' + } +].map(function (item, index) { + return Object.assign({}, item, { + id: index + 1 + }); +}); diff --git a/packages/amis-core/src/utils/helper.ts b/packages/amis-core/src/utils/helper.ts index 54b17ff18..ad18af94a 100644 --- a/packages/amis-core/src/utils/helper.ts +++ b/packages/amis-core/src/utils/helper.ts @@ -1472,10 +1472,14 @@ export function getScrollbarWidth() { } // 后续改用 FormulaExec['formula'] -function resolveValueByName(data: any, name?: string) { +function resolveValueByName( + data: any, + name?: string, + canAccessSuper?: boolean +) { return isPureVariable(name) ? resolveVariableAndFilter(name, data) - : resolveVariable(name, data); + : resolveVariable(name, data, canAccessSuper); } // 统一的获取 value 值方法 @@ -1486,10 +1490,13 @@ export function getPropValue< data?: any; defaultValue?: any; } ->(props: T, getter?: (props: T) => any) { +>(props: T, getter?: (props: T) => any, canAccessSuper?: boolean) { const {name, value, data, defaultValue} = props; return ( - value ?? getter?.(props) ?? resolveValueByName(data, name) ?? defaultValue + value ?? + getter?.(props) ?? + resolveValueByName(data, name, canAccessSuper) ?? + defaultValue ); } diff --git a/packages/amis-core/src/utils/resolveVariable.ts b/packages/amis-core/src/utils/resolveVariable.ts index e0b28517b..9ebf5bc1c 100644 --- a/packages/amis-core/src/utils/resolveVariable.ts +++ b/packages/amis-core/src/utils/resolveVariable.ts @@ -1,14 +1,22 @@ import {Evaluator, parse} from 'amis-formula'; import {getVariable} from './getVariable'; -export function resolveVariable(path?: string, data: any = {}): any { +export function resolveVariable( + path?: string, + data: any = {}, + canAccessSuper?: boolean +): any { if (path === '&' || path == '$$') { return data; } else if (!path || typeof path !== 'string') { return undefined; } else if (!~path.indexOf(':')) { // 简单用法直接用 getVariable - return getVariable(data, path[0] === '$' ? path.substring(1) : path); + return getVariable( + data, + path[0] === '$' ? path.substring(1) : path, + canAccessSuper + ); } // window:xxx ls:xxx.xxx diff --git a/packages/amis/__tests__/renderers/Form/__snapshots__/range.test.tsx.snap b/packages/amis/__tests__/renderers/Form/__snapshots__/range.test.tsx.snap index 9e9ac32d4..03b276697 100644 --- a/packages/amis/__tests__/renderers/Form/__snapshots__/range.test.tsx.snap +++ b/packages/amis/__tests__/renderers/Form/__snapshots__/range.test.tsx.snap @@ -277,7 +277,7 @@ exports[`Renderer:range with min & max & step & joinValues 1`] = ` class="cxd-TplField" > - The form + 表单 @@ -293,18 +293,6 @@ exports[`Renderer:range with min & max & step & joinValues 1`] = ` style="display: none;" type="submit" /> -
-
- {
- "range": {
- "min": 0.2,
- "max": 0.8
- }
-}
-
-