场景介绍
在日常开发调试表单页
的过程中,细心的小伙伴应该注意到,视图内的数据(通过vue调试工具看到的formData就是视图的数据)和最终通过服务端动作提交的数据不总是一致的,本文将带领大家解开疑惑。
为什么会出现这种现象?
出现这种情况都是当前模型上有关联关系字段的场景,以多对一(M2O)
场景为例,由于当前模型的关联关系字段是通过字段配置中的referenceFields
属性和当前模型的relationFields
属性进行关联的,所以提交数据的时候只需要拿到relationFields
配置的字段就可以了,没有必要再去多拿关联关系字段本身的数据。
结合业务场景说明
这里以商品模型和类目模型举例,商品模型内有个类目的m2o字段category
和对应的relationFields
字段categoryId
,数据提交到后端的时候前端默认会根据字段配置只获取categoryId
,而category
的整个对象都不会被提交。
package pro.shushi.pamirs.demo.api.model;
import pro.shushi.pamirs.demo.api.model.DemoItemCategory;
import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.common.CodeModel;
@Model.model(DemoItem.MODEL_MODEL)
@Model(displayName = "测试商品")
public class DemoItem extends CodeModel {
private static final long serialVersionUID = -5104390780952631397L;
public static final String MODEL_MODEL = "demo.DemoItem";
@Field.String
@Field(displayName = "商品名称")
private String name;
@Field.Integer
@Field(displayName = "类目ID")
private Long categoryId;
@Field.many2one
@Field.Relation(relationFields = {"categoryId"}, referenceFields = {"id"})
@Field(displayName = "商品类目")
private DemoItemCategory category;
}
前端是如何处理数据的
前端的字段组件提供了submit()
方法来让我们可以有就会在提交数据的时候改变数据。
// 字段组件基类
export class BaseFormItemWidget<
Value = unknown,
Props extends BaseFormItemWidgetProps = BaseFormItemWidgetProps
> extends BaseDataWidget<Props> {
/**
* 数据提交的方法,例如:m2o字段user(假设其关系字段为userId)的值{id: 1, name: 'xxx'},但是实际后端数据只需要其中的id,所以用m2o对应的关系字段userId提交数据就可以了
* @param submitValue
*/
public submit(submitValue: SubmitValue): ReturnPromise<Record<string, unknown> | SubmitRelationValue | undefined> {
return undefined;
}
}
这里先以FormStringFieldSingleWidget
组件处理密码类型的字段讲解。
密码一般在输入的时候是明文,为了提高提交到后端的安全性,可以将这个密码加密后再传到后端,后端再做进一步处理,这个场景中,视图中的密码和提交给后端的密码就出现了不一致的情况,
@SPI.ClassFactory(
BaseFieldWidget.Token({
viewType: [ViewType.Form, ViewType.Search],
ttype: ModelFieldType.String
})
)
export class FormStringFieldSingleWidget extends FormStringFieldWidget {
public submit(submitValue: SubmitValue) {
let finalValue = this.value;
/**
* 数据提交的时候,如果判断当前字段是否需要加密,需要加密的情况用encrypt函数做加密处理
*/
if (this.crypto && finalValue) {
finalValue = encrypt(finalValue);
}
return SubmitHandler.DEFAULT(this.field, this.itemName, submitValue, finalValue);
}
注意:关系字段配置的
透出字段
只影响该字段的查询数据方法的返回值,不会因为此配置就在提交数据里加上这部分配置的字段
字段需要提交关联关系字段内的所有数据如何处理?
我们可以在自定义组件里覆写submit()
方法,直接将this.value
内的数据返回
这里以覆写多对多m2m
字段为例
import {
BaseFieldWidget,
FormM2MFieldSelectWidget,
ModelFieldType,
SPI,
SubmitValue,
ViewType
} from '@kunlun/dependencies';
@SPI.ClassFactory(
BaseFieldWidget.Token({
viewType: ViewType.Form,
ttype: ModelFieldType.ManyToMany,
widget: 'Select',
model: 'xxx.yyyyy',
name: 'fileName01',
})
)
export class MyFormO2MSubmitAllSelectFieldWidget extends FormM2MFieldSelectWidget {
/**
* 提交数据的方法
* 重写后会将字段内所有数据都提交,默认的方法只会提交关联关系字段的数据
* @param submitValue
*/
public async submit(submitValue: SubmitValue) {
// this.itemName是当前字段名称
return { [this.itemName]: this.value };
}
}
Oinone社区 作者:nation原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/17155.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验