1、antd中给弹窗中的表单赋值报错信息:
翻译:在呈现与值关联的字段之前,不能设置窗体字段。您可以使用getFieldDecorator(id,options)
而不是v-decorator=“[id,options]”
在渲染之前注册它。
2、弹窗内容为子组件,代码:
父组件:
<!-- 复核窗口 -->
<a-modal
v-model="showCheck"
title="复核"
@ok="handleCheckOk"
@cancel="handleCancel"
:width="668"
:confirm-loading="confirmLoading"
>
<check-mod
ref="checkModal"
:siteTypeList="siteTypeList"
>
</check-mod>
</a-modal>
js
// 点击复核按钮
handleCheck(item) {
let checkData = {...item}
this.checkId = checkData.id
this.showCheck = true
// 调用子组件中赋值的方法
this.$nextTick(() => {
this.$refs.checkModal.setValues(checkData);
});
}
子组件:
setValues(value) {
console.log(value)
this.values = value
if(this.values) {
let inspectionTime
inspectionTime = this.values.inspectionTime
this.form.setFieldsValue({
inspectionTime,
...this.values
})
}
}
3、解决方法1:指定赋值,即表单中需要赋值一 一 赋值
setValues(value) {
console.log(value)
this.values = value
if(this.values) {
let inspectionTime
inspectionTime = this.values.inspectionTime
this.form.setFieldsValue({
inspectionTime,
stationCode: this.values.stationCode,
stationName: this.values.stationName,
stationAddress: this.values.stationAddress,
stationTypeName: this.values.stationTypeName,
orderType: this.values.stationType,
faultType: this.values.faultType,
maintainMode: this.values.maintainMode,
opeDetails: this.values.opeDetails,
maintainMeasures: this.values.maintainMeasures,
reviewRecord: this.values.reviewRecord,
fraction: this.values.fraction
})
}
}
如果表单项有很多,一 一赋值那就很麻烦了,所以
4、解决方法2:判断旧对象
setValues(value) {
let formData = this.form.getFieldsValue();
// 循环表单数据
for (let i in formData) {
// 判断传来的对象的每个属性是否有值或者为0,给新对象每个属性赋值
this.values[i] = value[i] || value[i] == 0 ? value[i] : undefined;
// 判断新对象每个属性的值是否为字符串
typeof this.values[i] == "string" ?
(this.values[i] = this.values[i].replace(/(^\s*)|(\s*$)/g, "")) :
"";
}
// 给表单赋值
this.form.setFieldsValue({
...this.values,
});
}
5、原因分析:setFieldsValue里面有表单没有的字段 导致报错,解决思路:通过定义一个新对象,循环表单的每个属性,在传来的数据对象value对象中,一一对应上表单的属性,把属性和值都给到新对象;简介的说:就是表单的所有项都给到一个新对象,而且新对象的值都来自于传值对象,最后用新对象去给表单赋值,这样就不会因为赋多或者赋少而导致的报错了!
6、如果使用了方法2还是报错,那就使用this.$nextTick()回调(或者延迟触发)
1、使用this.$nextTick()
// 获取到的原对象(用来渲染的数据对象)
let infoData = value.swDeviceInstall;
let formData;
let infoValues = {};
this.$nextTick(() => {
// 获取到表单的对象
formData = this.infoForm.getFieldsValue();
// 循环表单对象属性
for (let i in formData) {
// 渲染表单项,获取到每个属性,通过原对象对应表单每个属性的值,如果有值则给infoValues对象对应的属性赋值,否则赋值undefined
infoValues[i] = infoData[i] || infoData[i] == 0 ? infoData[i] : undefined;
// 判断infoValues对象的每个属性是否为字符串, 如果为字符串则去掉前后空格(0个或多个),否则为空字符串
typeof infoValues[i] == "string" ?
(infoValues[i] = infoValues[i].replace(/(^\s*)|(\s*$)/g, "")) :
"";
};
this.infoForm.setFieldsValue({
...infoValues,
communicationMode: !infoData.communicationMode
? undefined
: infoData.communicationMode.split(","),
devPowerSupply: !infoData.devPowerSupply
? undefined
: infoData.devPowerSupply.split(","),
fixedType: !infoData.fixedType
? undefined
: infoData.fixedType.split(",")
});
})
2、使用定时器
clearTimeout(timer)
var timer = setTimeout(() => {
formData = this.infoForm.getFieldsValue();
for (let i in formData) {
infoValues[i] = infoData[i] || infoData[i] == 0 ? infoData[i] : undefined;
typeof infoValues[i] == "string" ?
(infoValues[i] = infoValues[i].replace(/(^\s*)|(\s*$)/g, "")) :
"";
};
this.infoForm.setFieldsValue({
...infoValues,
communicationMode: !infoData.communicationMode
? undefined
: infoData.communicationMode.split(","),
devPowerSupply: !infoData.devPowerSupply
? undefined
: infoData.devPowerSupply.split(","),
fixedType: !infoData.fixedType
? undefined
: infoData.fixedType.split(",")
});
}, 200);
7、replace(/(^\s*)|(\s*$)/g, “”) 不理解的朋友们请往这边走https://blog.csdn.net/shenjun1992722/article/details/49895203
8、遇到日期组件的朋友可能还会有报错(如图),请看另一篇文章>(正在测试中…)>(加班中…)>目的地
天天给自己一个微笑,种下每天的阳光!