字段组件submit方法详解

场景介绍

在日常开发调试表单页的过程中,细心的小伙伴应该注意到,视图内的数据(通过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低代码应用平台体验

Like (0)
nation's avatarnation数式员工
Previous 2024年9月10日 am9:35
Next 2024年9月11日 am9:57

相关推荐

  • 前端环境和启动前端工程

    本节核心是带大家直观的感受下我们上节构建的demo模块,并搭建前端环境为后续学习打下基础 环境准备 配置NPM源 npm config set registry http://nexus.shushi.pro/repository/kunlun/ 登录NPM源账号 npm login –registry "http://nexus.shushi.pro/repository/kunlun/" # username、password、email 获取方式: # 1、请见oinone开源社区群公告,也可以联系oinone合作伙伴或服务人员; # 2、参考数式发过去的部署包(部署.zip)中的账号说明:docker-mvn-npm账号.md npm info underscore 环境准备参考 [前端环境准备Mac版本]https://doc.oinone.top/oio4/9225.html [前端环境准备Windows版本]https://doc.oinone.top/oio4/9226.html 启动前端工程 1、下载前端工程本地运行 [ss-front-modules.zip]ss-front-modules 2、解压下载后的工程,可以查看README.MD快速上手指南; 找到vue.config.js文件,修改devServer.proxy.pamirs.target为后端服务的地址和端口 const WidgetLoaderPlugin = require('@kunlun/widget-loader/dist/plugin.js').default; const Dotenv = require('dotenv-webpack'); module.exports = { lintOnSave: false, runtimeCompiler: true, configureWebpack: { module: { rules: [ { test: /\.widget$/, loader: '@kunlun/widget-loader' } ] }, plugins: [new WidgetLoaderPlugin(), new Dotenv()], resolveLoader: { alias: { '@kunlun/widget-loader': require.resolve('@kunlun/widget-loader') } } }, devServer: { port: 8081, disableHostCheck: true, progress: false, proxy: { pamirs: { // 支持跨域 changeOrigin: true, // 改成本地后端对应的IP和端口; 本地后端未启动的情况也可改成无代码后端IP和端口 target: 'http://192.168.0.121:8190' } } } }; 3、 安装依赖和运行在工程目录ss-front-modules下执行 # 安装依赖 npm i # 运行 npm run dev 4、若安装失败 检查本地node、npm、vue对应的版本 5、 如果启动报错 清除node_modules后重新 npm i mac清除命令:npm run cleanOs windows清除命令: npm run clean 注:要用localhost域名访问,.env文件这里也要改成localhost。如果开发中一定要出现前后端域名不一致,老版本Chrome会有问题,修改可以请参https://www.cnblogs.com/willingtolove/p/12350429.html。或者下载新版本Chrome 进入前端工程ss-front-modules文件目录下,执行 npm run dev,最后出现下图就代表启动成功 6、使用 http://127.0.0.1:8081/login 进行访问,并用admin账号登陆,默认密码为admin 5、点击左上角进行应用切换,会进入App Finder页面,可以看到所有已经安装的应用,可以对照boot的yml配置文件看。 在后续的学习过程中我们会不断完善示例中的模块。至此恭喜您,前端工程已经启动完成。 示例工程分层说明 # ss-boot 不做业务研发,只做包的组装和依赖 # ss-oinone 与Oinone结合层,这个工程结构可以把数式Oinone的改造收口,也是业务工程依赖的核心层 # ss-admin-widget 与界面设计器无代码的结合工程,在这个工程结构里可以把组件放在无代码平台上使用 # ss-project 模拟的项目工程,做某个项目的个性化开发

    2024年5月28日
    2.7K00
  • 界面设计器 扩展字段的查询上下文

    默认情况下oinone平台对于查询条件,只提供的当前登录用户这一个配置,但是允许开发者扩展 开发者可以在前端代码的main.ts进行扩展 import { SessionContextOptions, ModelFieldType } from '@kunlun/dependencies'; const currentDeptOption = { ttype: ModelFieldType.String, value: '$#{currentDept}', displayName: '当前登录部门', label: '当前登录部门' }; SessionContextOptions.push(currentDeptOption as any); 加上上面的代码,然后再去界面设计器,我们就会发现,多了一个配置

    2023年11月8日
    2.2K00
  • Oinone平台可视化调试工具

    为方便开发者定位问题,我们提供了可视化的调试工具。
    该文档将介绍可视化调试工具的基本使用方法。

    2024年4月13日
    1.6K00
  • 【前端】低无一体部署常见问题

    如何检查上传的SDK是否有效? 1. 在任意页面刷新后,查看是否发起【查询SDK组件】的请求。 2. 在返回的js和css列表中是否能找到在界面设计器上传的js和css文件。 3. 检查浏览器的Console中是否有组件相关报错。 4. 检查sdk中是否包含了启动工程未加入的包依赖。 启动工程包依赖:main.ts VueOioProvider( { dependencies: { vue: import('vue'), lodashEs: import('lodash-es'), antDesignVue: import('ant-design-vue'), elementPlusIconsVue: import('@element-plus/icons-vue'), elementPlus: import('element-plus'), kunlunDependencies: import('@kunlun/dependencies'), kunlunVueUiAntd: import('@kunlun/vue-ui-antd'), kunlunVueUiEl: import('@kunlun/vue-ui-el') } } ); SDK依赖:rollup.config.ts const globals = { vue: 'vue', 'lodash-es': 'lodashEs', 'ant-design-vue': 'antDesignVue', '@element-plus/icons-vue': 'elementPlusIconsVue', 'element-plus': 'elementPlus', '@kunlun/dependencies': 'kunlunDependencies', '@kunlun/vue-ui-antd': 'kunlunVueUiAntd', '@kunlun/vue-ui-el': 'kunlunVueUiEl', '@kunlun/mobile-dependencies': 'kunlunMobileDependencies', '@kunlun/vue-ui-mobile-vant': 'kunlunVueUiMobileVant' }; 上述两个文件配置的依赖和对应名称必须匹配才能在sdk上传后正常运行,否则会出现内存变量无法共享的问题。 当未发起【查询SDK组件】的请求时如何处理? 1. 在任意页面刷新后,查看manifest.js加载路径。 业务工程通常为:http://${host}:${port}/manifest.js 设计器镜像中通常为:http://${host}:${port}/config/manifest.js 2. 若未正确加载manifest.js,则在dist目录中根据请求路径添加manifest.js文件。此文件称为运行时配置文件,可点击查看参考文档。 runtimeConfigResolve({ plugins: { usingRemote: true } });

    低无一体 2023年11月1日
    2.5K00
  • 上下文在字段和动作中的应用

    上下文在字段和动作中的应用 在业务场景中,常常需要在打开弹窗或跳转到新页面时携带当前页面数据。此时,我们需要配置相关「动作」中的上下文信息。 在 oinone 平台中,上下文主要分为以下三种: activeRecord:当前视图数据 rootRecord:主视图数据 openerRecord:触发弹窗的对象 参考文档:oinone内的主视图数据和当前视图数据使用介绍 activeRecord 表示当前视图的数据。例如,若动作配置在表单上,则指代当前表单的数据;若配置在 o2m、m2m 字段表格上,则指代选中的行数据。 rootRecord 表示根视图的数据。若当前视图是表单页,则代表表单的数据;若为表格页,则代表表格的数据。 openerRecord 表示触发弹窗的对象。例如,在弹窗内的字段或动作中,可通过 openerRecord 获取触发弹窗的信息。 这三者均为对象 (Object) 类型。 界面设计器配置 在 o2m、m2m 表格字段弹窗中携带当前视图数据 假设我们设计了一个包含 o2m、m2m 表格字段的表单页面。打开相关弹窗时,需将表单中的 code 数据传递至弹窗中。 选择相应的「动作」,如创建或添加。在右侧属性面板底部找到「上下文」,添加格式为对象 {} 的上下文信息。 以键值对的格式添加上下文信息:{code: rootRecord.code}。 设计弹窗时,将 code 字段拖入弹窗中。 完成设计后保存并发布。 大家可以看到,上下文中的key是 code,但是value是rootRecord.code,这里取的是rootRecord而不是activeRecord,因为我们上面讲过如果当前动作配置在o2m、m2m的字段表格上面,那么activeRecord就是表格选中的行,我们现在要取的是表单上的code字段,所以需要用rootRecord。 注意点:key需要是提交模型【前端视图】存在的字段才能传递。

    2023年11月8日
    2.9K10

Leave a Reply

Please Login to Comment