chore: added selfPath and $path variables to describe chain path into dx expressions to current object of schema. this is the breaking change to use JS function signature in dx expressions

This commit is contained in:
Dmitry Nagibin
2020-10-28 19:09:23 +03:00
parent 5b8a655551
commit 769d988937
14 changed files with 247 additions and 95 deletions
+3 -2
View File
@@ -260,12 +260,13 @@ globalConfig: {
> dx expressions can also be replaced with `function` :
function(formData, constData, selfData, tempData, itemIdxChain) { ... }
function(formData, constData, selfData, tempData, selfPath, itemIdxChain) { ... }
- formData: corresponds to `{{$root}}`. Form data
- constData: corresponds to `{{$const}}`. Constant data in global configuration
- selfData: corresponds to `{{$self}}`. Used only for `ui.preview.value`, which refers to its own value
- tempData: corresponds to `{{$temp}}`. Temporarily stored value
- selfPath: corresponds to `{{$path}}`. To use self object type the construction into dx: `__get({{$root}}, {{$path}})`
- itemIdxChain: useful only for array items, refers to the index path of the current array, such as [1, 0]
Some common examples are as follows:
@@ -277,7 +278,7 @@ disabled: function(formData) {
}
// array item
disabled: function(formData, constData, selfData, tempData, itemIdxChain) {
disabled: function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
const [ i ] = itemIdxChain;
return formData.persons[i].age < 18;
}
+3 -2
View File
@@ -260,12 +260,13 @@ globalConfig: {
> dx表达式也可用 `函数` 代替:
function(formData, constData, selfData, tempData, itemIdxChain) { ... }
function(formData, constData, selfData, tempData, selfPath, itemIdxChain) { ... }
- formData:对应于 `{{$root}}`。表单的数据
- constData: 对应于 `{{$const}}`。全局配置中的常量数据
- selfData:对应于 `{{$self}}`。只用于 `ui.preview.value`,指代本身的值
- tempData:对应于 `{{$temp}}`。临时存储的值
- selfPath:对应于 `{{$path}}`。要使用自对象,请将结构键入dx`__get({{$root}}, {{$path}})`
- itemIdxChain:仅对数组项有用,指代当前所在的数组的索引路径,如[1, 0]
一些常见的例子如下:
@@ -277,7 +278,7 @@ disabled: function(formData) {
}
// 数组项
disabled: function(formData, constData, selfData, tempData, itemIdxChain) {
disabled: function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
const [ i ] = itemIdxChain;
return formData.persons[i].age < 18;
}
@@ -56,6 +56,11 @@ export default {
default: ""
},
paths: {
type: String,
default: ""
},
value: {
type: [String, Number, Boolean, Object, Array]
},
@@ -160,7 +165,8 @@ export default {
data: {
rootData: this.formData,
constData: this.globalConst,
tempData: this.tempData
tempData: this.tempData,
selfPath: this.paths
}
});
},
@@ -151,7 +151,8 @@ export default {
data: {
rootData: this.formData,
constData: this.globalConst,
tempData: this.tempData
tempData: this.tempData,
selfPath: this.paths + `[${(idx || "").split(",").slice(-1)[0]}]`
}
});
},
@@ -72,13 +72,14 @@ export default {
},
methods: {
_analyzeVal(val) {
_analyzeVal(val, key = "") {
return ncformUtils.smartAnalyzeVal(val, {
idxChain: this.idxChain,
data: {
rootData: this.formData,
constData: this.globalConst,
tempData: this.tempData
tempData: this.tempData,
selfPath: this.paths + (key !== "" ? `.${key}` : "")
}
});
},
+64 -41
View File
@@ -417,7 +417,7 @@ const ncformUtils = {
* @param {*} val
* @param {*}
* idxChain: 该值的索引链,即所在的路径中的所有数组中的索引,比如 persons[0].name[1].firstname,即该值为"0,1"
* data: {rootData: 代表$root的值, constData: 代表$const的值, selfData: 代表$self的值, tempData: 代表$tempData的值 }
* data: {rootData: 代表$root的值, constData: 代表$const的值, selfData: 代表$self的值, tempData: 代表$tempData的值, selfPath: 代表$path的值 }
* 规则:
* 1. 普通值直接返回
* 2. 函数类型返回执行后的值
@@ -427,7 +427,7 @@ const ncformUtils = {
val,
{
idxChain = "",
data = { rootData: {}, constData: {}, selfData: {}, tempData: {} }
data = { rootData: {}, constData: {}, selfData: {}, tempData: {}, selfPath: "" }
} = {}
) {
return ncformUtils.smartAnalyze(val, {
@@ -448,6 +448,10 @@ const ncformUtils = {
{
symbol: "$temp",
value: data.tempData
},
{
symbol: "$path",
value: data.selfPath
}
]
});
@@ -468,15 +472,68 @@ const ncformUtils = {
*/
smartAnalyze(val, { idxChain = "", data = [], expPrefix = "dx:" } = {}) {
const valType = typeof val;
const idxChains = idxChain.split(",");
let result;
const __get = _get;
const __map = _map;
const getSpec = tempVal => {
data.forEach((dataItem, idx) => {
if (tempVal.indexOf("[e]") >= 0) {
tempVal = tempVal.replace(
new RegExp(`\\{{\\s*\\${dataItem.symbol}(.*)}}`),
`__map(data[${idx}].value._value, '$1')`
);
} else {
tempVal = tempVal.replace(
new RegExp(`\\{{\\s*\\${dataItem.symbol}(\\.?.*)}}`),
`__get(data[${idx}].value, '_value$1')`
); // tempVal值:__get(_formData, 'persons[i].age')
}
});
return tempVal;
}
const fixSpec = tempVal => {
const brackets = tempVal.match(/\[.*?\]/g) || []; // brackets值:["[i]"]
brackets.forEach((bItem, idx) => {
// bItem值:"[i]"
if (bItem === "[e]") {
// e表达式 [e]
// before _map(data[0].value, '[e].id')
tempVal = tempVal
.replace(", '", "")
.replace(/\[e\]\.{0,1}/, ", '")
.replace(", ''", "");
// after __map(data[0].value, 'id')
} else {
// i表达式或者索引数字 [i] or [0]
const bItemTemp = eval(bItem.replace(/i/g, idxChains[idx - 1])); // bItemTemp值:[0] (假设idxChain[0] == 0
tempVal = tempVal.replace(bItem, `[${bItemTemp}]`); // tempVal值:__get(_formData, 'persons[0].age')
}
});
return tempVal;
}
const fixPath = tempVal => {
const brackets = tempVal.match(/\[.*?\]/g) || []; // brackets值:["[i]"]
brackets.forEach((bItem, idx) => {
if (bItem === "[i]") {
const bItemTemp = eval(bItem.replace(/i/g, idxChains[idx])); // bItemTemp值:[0] (假设idxChain[0] == 0
tempVal = tempVal.replace(bItem, `[${bItemTemp}]`); // tempVal值:'persons[0].age'
}
});
return tempVal;
}
data = data.map((
dataItem // 套多一层是为了支持原始类型,如string, number
) =>
Object.assign({}, dataItem, {
value: { _value: dataItem.value }
value: {
_value: dataItem.symbol === "$path" && typeof dataItem.value === "string" ?
fixPath(dataItem.value) : dataItem.value
}
})
);
@@ -484,43 +541,11 @@ const ncformUtils = {
case "string":
if (val.indexOf(expPrefix) === 0) {
// TODO daniel: 这里的替换可能需要再完善一下,可能会出错
const idxChains = idxChain.split(",");
// 假设val为:dx: {{$root.persons[i].age}} > 1 && {{$root.persons[i].age}} < 18
const matchs = val.match(/\{{.*?}}/g) || []; // matchs值:["{{$root.persons[i].age}}", "{{$root.persons[i].age}}"]
matchs.forEach(mItem => {
// mItem值:"{{$root.persons[i].age}}"
let tempVal = mItem;
data.forEach((dataItem, idx) => {
if (tempVal.indexOf("[e]") >= 0) {
tempVal = tempVal.replace(
new RegExp(`\\{{\\s*\\${dataItem.symbol}(.*)}}`),
`__map(data[${idx}].value._value, '$1')`
);
} else {
tempVal = tempVal.replace(
new RegExp(`\\{{\\s*\\${dataItem.symbol}(\\.?.*)}}`),
`__get(data[${idx}].value, '_value$1')`
); // tempVal值:__get(_formData, 'persons[i].age')
}
});
const brackets = tempVal.match(/\[.*?\]/g) || []; // brackets值:["[i]"]
brackets.forEach((bItem, idx) => {
// bItem值:"[i]"
if (bItem === "[e]") {
// e表达式 [e]
// before _map(data[0].value, '[e].id')
tempVal = tempVal
.replace(", '", "")
.replace(/\[e\]\.{0,1}/, ", '")
.replace(", ''", "");
// after __map(data[0].value, 'id')
} else {
// i表达式或者索引数字 [i] or [0]
const bItemTemp = eval(bItem.replace(/i/g, idxChains[idx - 1])); // bItemTemp值:[0] (假设idxChain[0] == 0
tempVal = tempVal.replace(bItem, `[${bItemTemp}]`); // tempVal值:__get(_formData, 'persons[0].age')
}
});
val = val.replace(mItem, tempVal);
val = val.replace(mItem, fixSpec(getSpec(mItem)));
});
result = eval(val);
} else {
@@ -528,12 +553,10 @@ const ncformUtils = {
}
break;
case "function":
const idxChains = idxChain
.split(",")
.filter(item => item)
.map(item => parseInt(item));
result = val(
...data.map(item => item.value._value).concat([idxChains])
...data.map(item => item.value._value).concat([idxChains
.filter(item => item)
.map(item => parseInt(item))])
);
break;
default:
@@ -887,11 +887,22 @@ describe('/src/ncform-utils.js', () => {
assert(result === true);
});
it("smartAnalyzeVal - function get path", () => {
const rootData = { name: 'daniel', sign: '!' };
const sayHi = 'hi';
const val = function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
return `${sayHi} ${formData.name}${formData[selfPath]}` === 'hi daniel!';
};
const result = ncformUtils.smartAnalyzeVal(val, { data: { rootData, selfPath: "sign" } });
assert(result === true);
});
it("smartAnalyzeVal - function value array item", () => {
let rootData = { users: [{ name: 'daniel' }, { name: 'sarah' }] };
const sayHi = 'hi';
let val = function(formData, constData, selfData, tempData, itemIdxChain) {
let val = function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
return `${sayHi} ${formData.users[itemIdxChain[0]].name}` === 'hi sarah';
};
let result = ncformUtils.smartAnalyzeVal(val, {
@@ -904,7 +915,7 @@ describe('/src/ncform-utils.js', () => {
users: [{ address: [{ name: 'beijing' }, { name: 'shanghai' }] }]
};
val = function(formData, constData, selfData, tempData, itemIdxChain) {
val = function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
const [i, j] = itemIdxChain;
return `${sayHi} ${formData.users[i].address[j].name}` === 'hi shanghai';
};
@@ -913,6 +924,15 @@ describe('/src/ncform-utils.js', () => {
data: { rootData }
});
assert(result === true);
val = function(formData, constData, selfData, tempData, selfPath, itemIdxChain) {
return `${selfPath}` === 'users[0].address[1].name';
};
result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '0,1',
data: { rootData, selfPath: "users[i].address[i].name" }
});
assert(result === true);
});
it("smartAnalyzeVal - special string", () => {
@@ -950,6 +970,20 @@ describe('/src/ncform-utils.js', () => {
data: { selfData: 'hello daniel' }
});
assert(result === 'hello daniel');
val = 'dx: {{$path}}';
result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '0',
data: { selfPath: 'persons[i].age' }
});
assert(result === 'persons[0].age');
val = 'dx: __get({{$root}}, {{$path}})';
result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '1',
data: { rootData, selfPath: 'persons[i].age' }
});
assert(result === 20);
});
it("smartAnalyzeVal - special string nested array", () => {
@@ -957,12 +991,26 @@ describe('/src/ncform-utils.js', () => {
persons: [[{ age: 12 }, { age: 18 }], [{ age: 50 }, { age: 80 }]]
};
const val = 'dx: {{$root.persons[i][i].age}} === 50';
const result = ncformUtils.smartAnalyzeVal(val, {
let val = 'dx: {{$root.persons[i][i].age}} === 50';
let result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '1,0',
data: { rootData }
});
assert(result === true);
val = 'dx: __get({{$root}}, {{$path}}) === 50';
result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '1,0',
data: { rootData, selfPath: 'persons[i][i].age' }
});
assert(result === true);
val = 'dx: __get({{$root}}, {{$path}}) === 18';
result = ncformUtils.smartAnalyzeVal(val, {
idxChain: '0,1',
data: { rootData, selfPath: 'persons[i][i].age' }
});
assert(result === true);
});
// --- smartAnalyze
@@ -175,8 +175,16 @@
methods: {
analyzeItemVal(val, idxChain) {
return ncformUtils.smartAnalyzeVal(val, { idxChain: idxChain + '', data: { rootData: this.formData, constData: this.globalConst } });
return ncformUtils.smartAnalyzeVal(val, {
idxChain: idxChain + '',
data: {
rootData: this.formData,
constData: this.globalConst,
selfPath: this.paths + `[${idxChain}]`
}
});
},
showRequiredFlag(requiredConfig) {
if (!requiredConfig) return false;
@@ -10,15 +10,15 @@
<div v-for="(fieldSchema, field) in filteredPropreties"
:key="field"
:class="['el-col-' + ((_analyzeVal(fieldSchema.ui.columns) || 12) * 2 || 24)]"
:style="{display: hidden(fieldSchema) ? 'none' : ''}"
:class="['el-col-' + ((_analyzeVal(fieldSchema.ui.columns, field) || 12) * 2 || 24)]"
:style="{display: hidden(fieldSchema, field) ? 'none' : ''}"
class="el-col el-form-item">
<template>
<label v-if="!fieldSchema.ui.noLabelSpace" :style="{'visibility': fieldSchema.ui.showLabel ? 'visible' : 'hidden'}" class="el-form-item__label">
<!-- 必填标识 -->
<i v-if="_analyzeVal(fieldSchema.rules.required) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label)}}
<i v-if="_analyzeVal(fieldSchema.rules.required, field) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value, field) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label, field)}}
<!-- 提示信息 -->
<el-tooltip v-if="fieldSchema.ui.help.show === true" class="item" effect="dark" :content="fieldSchema.ui.help.content" placement="right-start">
<div slot="content" v-html="fieldSchema.ui.help.content"></div>
@@ -31,7 +31,7 @@
</div>
<!-- 说明信息 -->
<small v-if="fieldSchema.ui.description" class="form-desc" v-html="_analyzeVal(fieldSchema.ui.description)">
<small v-if="fieldSchema.ui.description" class="form-desc" v-html="_analyzeVal(fieldSchema.ui.description, field)">
</small>
</template>
@@ -43,14 +43,14 @@
<div v-if="mergeConfig.layout === 'h'" v-show="!collapsed" class="el-row h-layout" style="width: 100%">
<div v-for="(fieldSchema, field) in filteredPropreties"
:key="field"
:class="['el-col-' + ((_analyzeVal(fieldSchema.ui.columns) || 12) * 2 || 24)]"
:style="{display: hidden(fieldSchema) ? 'none' : ''}"
:class="['el-col-' + ((_analyzeVal(fieldSchema.ui.columns, field) || 12) * 2 || 24)]"
:style="{display: hidden(fieldSchema, field) ? 'none' : ''}"
class="el-col el-form-item">
<template>
<label v-if="!fieldSchema.ui.noLabelSpace" :style="{'visibility': fieldSchema.ui.showLabel ? 'visible' : 'hidden', width: mergeConfig.labelWidth}" class="el-form-item__label">
<!-- 必填标识 -->
<i v-if="_analyzeVal(fieldSchema.rules.required) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label)}}
<i v-if="_analyzeVal(fieldSchema.rules.required, field) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value, field) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label, field)}}
<!-- 提示信息 -->
<el-tooltip class="item" effect="dark" placement="right-start">
<div slot="content" v-html="fieldSchema.ui.help.content"></div>
@@ -61,7 +61,7 @@
<div class="el-form-item__content" :style="{'margin-left': (fieldSchema.ui.noLabelSpace) ? '0px' : mergeConfig.labelWidth}">
<slot :name="field"></slot>
<!-- 说明信息 -->
<small v-if="fieldSchema.ui.description" class="form-desc" v-html="_analyzeVal(fieldSchema.ui.description)">
<small v-if="fieldSchema.ui.description" class="form-desc" v-html="_analyzeVal(fieldSchema.ui.description, field)">
</small>
</div>
</template>
@@ -179,7 +179,7 @@ export default {
const { properties } = this.schema
return Object.keys(properties).reduce((result, curkey) => {
const curval = properties[curkey]
const remove = this._analyzeVal(curval.ui.remove)
const remove = this._analyzeVal(curval.ui.remove, curkey)
if (remove) {
const fullkey = paths ? paths + '.' + curkey : curkey
@@ -196,13 +196,13 @@ export default {
legendEnable(fieldSchema) {
return fieldSchema.ui && fieldSchema.ui.showLegend && fieldSchema.ui.legend;
},
hidden(fieldSchema) {
hidden(fieldSchema, field) {
if ( !fieldSchema || fieldSchema.ui.process === true || fieldSchema.ui.process === undefined ) {
return this._analyzeVal(fieldSchema.ui.hidden);
return this._analyzeVal(fieldSchema.ui.hidden, field);
}
let nodeCodeArr = this.globalConst.nodeCodeArr || []
if ((nodeCodeArr.includes(fieldSchema.ui.process) || fieldSchema.ui.process === this.globalConst.nodeUId)) {
return this._analyzeVal(fieldSchema.ui.hidden)
return this._analyzeVal(fieldSchema.ui.hidden, field)
} else {
return true
}
@@ -6,7 +6,17 @@
<component v-if="isNormalObjSchema(schema)" :is="'ncform-' + schema.ui.widget" :schema="schema" :paths="paths" v-bind="commonAttrs">
<template v-for="(fieldSchema, fieldName) in schema.properties" :slot="fieldName">
<form-item :schema="fieldSchema" :form-data="formData" :temp-data="tempData" :global-const="globalConfig.constants" :key="`${formName}-${fieldName}`" :global-config="globalConfig" :idx-chain="idxChain" :complete-schema="completeSchema" :paths="paths ? paths + '.' + fieldName : fieldName" :form-name="formName"></form-item>
<form-item
:schema="fieldSchema"
:form-data="formData"
:temp-data="tempData"
:global-const="globalConfig.constants"
:key="`${formName}-${fieldName}`"
:global-config="globalConfig"
:idx-chain="idxChain"
:complete-schema="completeSchema"
:paths="paths ? paths + '.' + fieldName : fieldName"
:form-name="formName"></form-item>
</template>
</component>
@@ -15,7 +25,17 @@
<component v-else-if="isNormalArrSchema(schema)" :is="'ncform-' + schema.ui.widget" :schema="schema" :paths="paths" v-bind="commonAttrs" class="__ncform-control">
<template v-for="(fieldSchema, fieldName) in (schema.items.properties || {__notObjItem: schema.items})" :slot="fieldName" slot-scope="props">
<form-item :schema="props.schema" :key="`${formName}-${fieldName}`" :form-data="formData" :temp-data="tempData" :global-const="globalConfig.constants" :idx-chain="(idxChain ? idxChain + ',' : '') + props.idx" :global-config="globalConfig" :complete-schema="completeSchema" :paths="paths + '[' + props.idx + ']' + (fieldName === '__notObjItem' ? '' : `.${fieldName}`)" :form-name="formName"></form-item>
<form-item
:schema="props.schema"
:key="`${formName}-${fieldName}`"
:form-data="formData"
:temp-data="tempData"
:global-const="globalConfig.constants"
:idx-chain="(idxChain ? idxChain + ',' : '') + props.idx"
:global-config="globalConfig"
:complete-schema="completeSchema"
:paths="paths + '[' + props.idx + ']' + (fieldName === '__notObjItem' ? '' : `.${fieldName}`)"
:form-name="formName"></form-item>
</template>
</component>
@@ -180,7 +200,8 @@ export default {
data: {
rootData: this.formData,
tempData: this.tempData,
constData: this.globalConfig.constants
constData: this.globalConfig.constants,
selfPath: this.paths
}
});
@@ -192,7 +213,8 @@ export default {
data: {
rootData: this.formData,
tempData: this.tempData,
constData: this.globalConfig.constants
constData: this.globalConfig.constants,
selfPath: this.paths
}
});
}
@@ -211,7 +233,8 @@ export default {
rootData: this.formData,
tempData: this.tempData,
constData: this.globalConfig.constants,
selfData: modelVal
selfData: modelVal,
selfPath: this.paths
}
});
},
@@ -245,6 +268,7 @@ export default {
.validate(val, rules, {
formData: this.formData,
tempData: this.tempData,
selfPath: this.paths,
idxChain: idxChain,
globalConfig: this.globalConfig
})
@@ -314,6 +338,7 @@ export default {
{
formData: this.formData,
tempData: this.tempData,
selfPath: this.paths,
idxChain: this.idxChain,
globalConfig: this.globalConfig
},
@@ -334,7 +359,8 @@ export default {
data: {
rootData: this.formData,
tempData: this.tempData,
constData: this.globalConfig.constants
constData: this.globalConfig.constants,
selfPath: this.paths
}
})
);
@@ -349,6 +375,7 @@ export default {
.validate(val, rules, {
formData: this.formData,
tempData: this.tempData,
selfPath: this.paths,
idxChain: this.idxChain,
globalConfig: this.globalConfig
})
@@ -131,7 +131,14 @@
methods: {
analyzeItemVal(val, idxChain) {
return ncformUtils.smartAnalyzeVal(val, { idxChain: idxChain + '', data: { rootData: this.formData, constData: this.globalConst } });
return ncformUtils.smartAnalyzeVal(val, {
idxChain: idxChain + '',
data: {
rootData: this.formData,
constData: this.globalConst,
selfPath: this.paths + `[${idxChain}]`
}
});
},
showRequiredFlag(requiredConfig) {
@@ -6,15 +6,15 @@
<div v-if="mergeConfig.layout === 'v'" v-show="!collapsed" class="form-row v-layout" style="width: 100%">
<div v-for="(fieldSchema, field) in filteredPropreties"
:key="field"
:class="['col-md-' + (_analyzeVal(fieldSchema.ui.columns) || 12)]"
:style="{display: _analyzeVal(fieldSchema.ui.hidden) ? 'none' : ''}"
:class="['col-md-' + (_analyzeVal(fieldSchema.ui.columns, field) || 12)]"
:style="{display: _analyzeVal(fieldSchema.ui.hidden, field) ? 'none' : ''}"
class="form-group">
<template>
<label v-if="!legendEnable(fieldSchema) && !fieldSchema.ui.noLabelSpace" :style="{'visibility': fieldSchema.ui.showLabel ? 'visible' : 'hidden'}">
<!-- 必填标识 -->
<i v-if="_analyzeVal(fieldSchema.rules.required) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value) === true)" class="text-danger">*</i>
<i v-if="_analyzeVal(fieldSchema.rules.required, field) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value, field) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label)}}
{{_analyzeVal(fieldSchema.ui.label, field)}}
<!-- 提示信息 -->
<a v-if="fieldSchema.ui.help.show === true" :title="fieldSchema.ui.help.content" href="#"><span :class="fieldSchema.ui.help.iconCls">{{fieldSchema.ui.help.text}}</span></a>
@@ -23,7 +23,7 @@
<slot :name="field"></slot>
<!-- 说明信息 -->
<small v-if="fieldSchema.ui.description" class="form-text text-muted" v-html="_analyzeVal(fieldSchema.ui.description)">
<small v-if="fieldSchema.ui.description" class="form-text text-muted" v-html="_analyzeVal(fieldSchema.ui.description, field)">
</small>
</template>
@@ -34,14 +34,14 @@
<div v-if="mergeConfig.layout === 'h'" v-show="!collapsed" class="form-row h-layout" style="width: 100%">
<div v-for="(fieldSchema, field) in filteredPropreties"
:key="field"
:class="['col-md-' + (_analyzeVal(fieldSchema.ui.columns) || 12)]"
:style="{display: _analyzeVal(fieldSchema.ui.hidden) ? 'none' : ''}"
:class="['col-md-' + (_analyzeVal(fieldSchema.ui.columns, field) || 12)]"
:style="{display: _analyzeVal(fieldSchema.ui.hidden, field) ? 'none' : ''}"
class="form-group row">
<template>
<label v-if="!legendEnable(fieldSchema) && !fieldSchema.ui.noLabelSpace" :style="{'visibility': fieldSchema.ui.showLabel ? 'visible' : 'hidden', width: mergeConfig.labelWidth}" class="col-form-label">
<!-- 必填标识 -->
<i v-if="_analyzeVal(fieldSchema.rules.required) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label)}}
<i v-if="_analyzeVal(fieldSchema.rules.required, field) === true || (typeof fieldSchema.rules.required === 'object' && _analyzeVal(fieldSchema.rules.required.value, field) === true)" class="text-danger">*</i>
{{_analyzeVal(fieldSchema.ui.label, field)}}
<!-- 提示信息 -->
<a v-if="fieldSchema.ui.help.show === true" :title="fieldSchema.ui.help.content" href="#"><span :class="fieldSchema.ui.help.iconCls">{{fieldSchema.ui.help.text}}</span></a>
@@ -51,7 +51,7 @@
<slot :name="field"></slot>
<!-- 说明信息 -->
<small v-if="fieldSchema.ui.description" class="form-text text-muted" v-html="_analyzeVal(fieldSchema.ui.description)">
<small v-if="fieldSchema.ui.description" class="form-text text-muted" v-html="_analyzeVal(fieldSchema.ui.description, field)">
</small>
</div>
</template>
@@ -112,7 +112,7 @@
const { properties } = this.schema
return Object.keys(properties).reduce((result, curkey) => {
const curval = properties[curkey]
const remove = this._analyzeVal(curval.ui.remove)
const remove = this._analyzeVal(curval.ui.remove, curkey)
if (!remove) {
result[curkey] = curval
@@ -1,7 +1,13 @@
<template>
<div class="ncform">
<form v-if="!isSchemaChanging" novalidate :class="dataFormSchema.globalConfig.style.formCls">
<form-item :schema="dataFormSchema" :form-data="formData" :temp-data="tempData" :global-config="dataFormSchema.globalConfig" :complete-schema="dataFormSchema" :form-name="name"></form-item>
<form-item
:schema="dataFormSchema"
:form-data="formData"
:temp-data="tempData"
:global-config="dataFormSchema.globalConfig"
:complete-schema="dataFormSchema"
:form-name="name"></form-item>
<!-- button这样处理是为了在Mac下的Safari能否正常使用回车键触发表单的submit事件 -->
<button @click.prevent="submit()" type="submit" style="position: absolute; left: -100px; visibility: hidden"></button>
</form>
@@ -201,7 +207,8 @@ export default {
idxChain: __idxChain,
data: {
rootData: this.$data.formData,
constData: this.dataFormSchema.globalConfig.constants
constData: this.dataFormSchema.globalConfig.constants,
selfPath: __dataPath === undefined ? '' : __dataPath
}
});
if (isRemove)
@@ -217,7 +224,8 @@ export default {
idxChain: __idxChain,
data: {
rootData: this.$data.formData,
constData: this.dataFormSchema.globalConfig.constants
constData: this.dataFormSchema.globalConfig.constants,
selfPath: __dataPath === undefined ? '' : __dataPath
}
});
} else {
@@ -244,6 +252,7 @@ export default {
window.__$ncform.__ncformRegularValidation
.validate(schema.value, schema.rules, {
formData: this.$data.formData,
selfPath: __dataPath,
idxChain: __idxChain,
globalConfig: this.dataFormSchema.globalConfig
})
+26 -6
View File
@@ -12,7 +12,7 @@ class RegularValidation {
validate(
value,
rules = {},
{ formData, idxChain = "", globalConfig = {} },
{ formData, selfPath = "", idxChain = "", globalConfig = {} },
uniqueId = ""
) {
const keys = Object.keys(rules);
@@ -40,7 +40,11 @@ class RegularValidation {
if (
!ncformUtils.smartAnalyzeVal(item.script, {
idxChain,
data: { rootData: formData, constData: globalConfig.constants }
data: {
rootData: formData,
constData: globalConfig.constants,
selfPath: selfPath
}
})
) {
resolve({
@@ -81,12 +85,20 @@ class RegularValidation {
dxRules = _cloneDeep(rules[keys[i]]);
dxRules.value = ncformUtils.smartAnalyzeVal(rules[keys[i]].value, {
idxChain,
data: { rootData: formData, constData: globalConfig.constants }
data: {
rootData: formData,
constData: globalConfig.constants,
selfPath: selfPath
}
});
} else {
dxRules = ncformUtils.smartAnalyzeVal(rules[keys[i]], {
idxChain,
data: { rootData: formData, constData: globalConfig.constants }
data: {
rootData: formData,
constData: globalConfig.constants,
selfPath: selfPath
}
});
}
@@ -148,11 +160,19 @@ class RegularValidation {
(keys.indexOf("required") === -1 ||
ncformUtils.smartAnalyzeVal(rules.required, {
idxChain,
data: { rootData: formData, constData: globalConfig.constants }
data: {
rootData: formData,
constData: globalConfig.constants,
selfPath: selfPath
}
}) === false ||
ncformUtils.smartAnalyzeVal(_get(rules, "required.value"), {
idxChain,
data: { rootData: formData, constData: globalConfig.constants }
data: {
rootData: formData,
constData: globalConfig.constants,
selfPath: selfPath
}
}) === false) &&
!ncformUtils.notEmptyVal(value)
) {