表格如何支持表尾合计计算

介绍

可以通过扩展TableWidget.ts实现

示例代码

import {
  BaseElementWidget,
  DslDefinitionType,
  SPI,
  TableWidget,
  ViewType,
  Widget
} from '@kunlun/dependencies';

@SPI.ClassFactory(
  BaseElementWidget.Token({
    type: ViewType.Table,
    widget: 'table',
    model: 'resource.k2.Model0000000109',
    viewName: '移动端品牌_TABLE_0000000000021513'
  })
)
export class FooterStatisticsTable extends TableWidget {
  public initialize(props) {
    if (props.template) {
      props.template?.widgets?.forEach((a) => {
        if (a.dslNodeType === DslDefinitionType.FIELD && this.statisticsFieldList.includes(a.name)) {
          a.statistics = true;
        }
      });
    }
    super.initialize(props);
    return this;
  }

  // 需要表尾做合并的字段名称
  public statisticsFieldList = ['fansNum'];

  @Widget.Reactive()
  protected get showFooter(): boolean | undefined {
    return true;
  }
}

效果预览

表格如何支持表尾合计计算

Oinone社区 作者:nation原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/17427.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
nation的头像nation数式员工
上一篇 2024年10月10日 pm9:55
下一篇 2024年10月15日 pm5:38

相关推荐

  • 组件数据交互基础(v4)

    阅读之前 你应该: 了解DSL相关内容。母版-布局-DSL 渲染基础(v4) 了解SPI机制相关内容。组件SPI机制(v4) 了解组件相关内容。 Class Component(ts)(v4) 组件生命周期(v4) 组件数据交互概述 数据结构设计 数据结构分为三大类,列表(List)、对象(Object)以及弹出层(Popup)。 列表(List):用于多条数据的展示,主要包括搜索(用户端)、自定义条件(产品端)、排序、分页、数据选中、数据提交、数据校验功能。 对象(Object):用于单条数据的展示,主要包括数据提交、数据校验功能。 弹出层(Popup):用于在一块独立的空间展示对应类型的数据。 数据结构与对于的内置视图类型: 列表(List):表格视图(TABLE)、画廊视图(GALLERY) 对象(Object):表单视图(FORM)、详情视图(DETAIL) 数据交互设计原则 组件与组件之间的结构关系是独立的,组件与组件之间的数据是关联的。因此,数据交互整体采用“作用域隔离(View),行为互通(CallChaining),数据互通(ActiveRecords)”这样的基本原则进行设计。实现时,围绕不同视图类型定义了一类数据结构所需的基本属性。 在弹出层进行设计时,使用Submetadata的方式,将包括弹出层在内的所有组件包含在内,以形成新的作用域。 通用属性及方法 属性 rootData:根数据源 dataSource:当前数据源 activeRecords:当前激活数据源 为了在实现时包含所有数据结构,我们统一采用ActiveRecord[]类型为所有数据源的类型,这些数据源在不同类型的视图中表示不同的含义: 列表(List):dataSource为列表当前数据源,activeRecords为列表中被选中的数据。特别的,showDataSource为当前展示的数据源,它是dataSource经过搜索、排序、分页等处理后的数据源,也是我们在组件中真正使用的数据源。 对象(Object):daraSource和activeRecords总是完全一致的,且长度永远为1。因此我们有时也在组件中定义formData属性,并提供默认实现:this.activeRecords?.[0] || {}。 方法 reloadDataSource:重载当前数据源 reloadActiveRecords:重载当前激活数据源 由于底层实现并不能正确判断当前使用的数据类型,因此我们无法采用统一标准的数据源修改方法,这时候需要开发者们自行判断。 重载列表数据源 cosnt dataSource: ActiveRecord[] = 新的数据源 // 重载数据源 this.reloadDataSource(dataSource); // 重置选中行 this.reloadActiveRecords([]); 重载表单数据源 cosnt dataSource: ActiveRecord[] = 新的数据源(数组中有且仅有一项) // 重载数据源 this.reloadDataSource(dataSource); // 此处必须保持相同引用 this.reloadActiveRecords(dataSource); 内置CallChaining(链式调用) 在自动化渲染过程中,我们通常无法明确知道当前组件与子组件交互的具体情况,甚至我们在定义当前组件时,并不需要关心(某些情况下可能无法关心)子组件的具体情况。这也决定了我们无法在任何一个组件中完整定义所需的一切功能。 为了保证组件行为的一致性,我们需要某些行为在各个组件的实现需要做到组件自治。以表格视图为例:当view标签在挂载时,我们无法确定应该怎样正确的加载数据,因此,我们需要交给一个具体的element标签来完成这一功能。当element标签对应的组件发生变化时,只需按照既定的重载方式将数据源提交给view标签即可。 除了保证组件行为的一致性外,我们不能完全的信任第三方框架对组件生命周期的处理顺序。因此,我们还需要对组件行为进行进一步的有序处理。以表格视图为例:我们希望搜索视图(SEARCH)的处理总是在加载数据前就处理完成的,这样将可以保证我们加载数据可以正确处理搜索条件,而这一特性并不随着模板结构的变化而发生变化。 平台内置的CallChaining mountedCallChaining:挂载时钩子; refreshCallChaining:刷新时钩子; submitCallChaining:提交时钩子; validatorCallChaining:验证时钩子; 优先级常量 VIEW_WIDGET_PRIORITY(0):视图组件优先级 FETCH_DATA_WIDGET_PRIORITY(100):数据提供者组件优先级 SUBVIEW_WIDGET_PRIORITY(200):子视图组件优先级 未设置优先级的hook将最后执行,在通常情况下,你无需关心优先级的问题。 注意事项 CallChaining通常不需要手动初始化,仅需通过inject方式获取即可。 CallChaining的hook/unhook方法需要在组件生命周期的mounted/unmounted分别执行,如无特殊情况,一般通过this.path作为挂载钩子的唯一键。 在字段组件中使用mountedCallChaing @Widget.Reactive() @Widget.Inject() protected mountedCallChaining: CallChaining | undefined; protected mountedProcess() { // 挂载时处理 } protected mounted() { super.mounted(); this.mountedCallChaining?.hook(this.path, () => { this.mountedProcess(); }); } protected unmounted() { super.unmounted(); this.mountedCallChaining?.unhook(this.path); } 字段组件的mountedCallChaing并不是必须的,因此我们未进行内置处理。 一般的,当视图数据被加载完成时,字段组件的formData和value等属性,将通过响应式自动获取对应的值,因此在大多数情况下是不需要使用这一特性的。 当我们需要对字段获取的值做进一步初始化处理时,我们将需要使用这一特性。例如TreeSelect组件,必须在初始化时填充树下拉所需的结构化数据,这样才能正确展示对应的值。 当字段组件的mounted方法被执行时,我们还未执行视图数据加载,因此,在我们无法在mounted方法中操作formData和value等属性,只有在mountedCallChaining被view标签执行时,按照执行顺序,此时字段的mountedChaining将在视图数据被加载完成后执行。 数据源持有者和数据源提供者 在设计上,我们通常将view标签设计为数据源持有者,将element标签设计为数据源提供者。 原则上,在一个视图中有且仅有一个数据源提供者。 即:当一个element标签的实现组件通过reloadDataSource方法向view标签设置数据源,我们就称该实现组件为当前view标签的数据源提供者,view标签为数据源持有者。 provider/inject 阅读该章节需要理解vue的依赖注入原理 在实现上,我们通过provider/inject机制将上述通用属性/方法进行交替处理,就可以实现根据模板定义的结构进行隔离和共享功能。 例如dataSource属性的实现: /** * 上级数据源 * @protected */ @Widget.Reactive() @Widget.Inject('dataSource') protected parentDataSource: ActiveRecord[] | undefined; /** * 当前数据源 * @protected */ @Widget.Reactive() private currentDataSource: ActiveRecord[] | null | undefined; /** * 提供给下级的数据源 * @protected */ @Widget.Reactive() @Widget.Provide() public get dataSource(): ActiveRecord[] | undefined { return this.currentDataSource || this.parentDataSource; } 不足的是,由于provider/inject机制特性决定,通过provider提供的属性和方法,在某些情况下可能会进行穿透,导致组件通过inject获取的属性和方法并非是我们所期望的那样,因此,我们仍然需要进行一些特殊的处理,才能正确的处理子视图的数据交互,这一点在对象(Object)类型的视图中会详细介绍。 运行时上下文(metadataHandle/rootHandle) 在之前的文章中,我们知道前端的字段/动作组件渲染和后端元数据之间是密不可分的。 在数据交互方面,后端元数据对于字段类型的定义,将决定从API接口中获取的字段、数据类型和格式,以及通过API接口提交数据到后端时的字段、数据类型和格式。 数据类型和格式可以通过field标签的data属性,获取到经过后端编译的相关字段元数据。 那么,我们该如何决定,当数据提供者向后端发起请求时,应该获取哪些字段呢? 因此,我们设计了RuntimeContext机制,并通过metadataHandle/rootHandle机制,在任何一个组件都可以通过view标签正确获取已经实现隔离的运行时上下文机制。 以表单视图为例,我们来看这样一个经过合并后的完整视图模板: (以下模板所展示的并非实际的运行时的结果,而是为了方便描述所提供的完整视图模板) <view type="FORM"> <element widget="actions"> <action…

    2023年11月1日
    1.5K00
  • [前端]平台内置的基类

    前端平台内置了多个基类,允许开发者通过继承的方式来实现字段、视图以及动作。以下是一些常见的基类: 视图基类 通用视图基类 BaseElementWidget BaseElementWidget 是所有视图的通用基类,无论是何种视图,都可以继承这个基类。它封装了一系列属性和API,帮助开发者更轻松地创建各种视图组件。 表单类型的视图基类 BaseElementObjectViewWidget BaseElementObjectViewWidget 是表单视图的基类,它是BaseElementWidget的扩展。这个基类内部自动处理请求发起,以及数据刷新等一系列操作。 表格类型的视图基类 BaseElementListViewWidget BaseElementListViewWidget 是表格视图的基类,同样也是基于BaseElementWidget的扩展。它内部处理自动请求发起和数据刷新等操作,与BaseElementObjectViewWidget类似。 字段基类 表单字段基类 FormFieldWidget FormFieldWidget 是表单字段的基类,它封装了一系列属性和API,用于简化表单字段的开发。 表格字段基类 BaseTableFieldWidget BaseTableFieldWidget 是表格字段的基类,它封装了一系列属性和API,有助于开发者更轻松地创建表格字段。 动作基类 服务端动作基类 ServerActionWidget 跳转动作基类 RouterViewActionWidget 跳转动作基类(打开抽屉) DrawerViewActionWidget 跳转动作基类(打开抽屉) DrawerViewActionWidget 通过使用这些基类,开发者可以提高代码的可重用性和可维护性,从而更高效地开发前端应用。这些基类旨在帮助开发者更轻松地构建功能丰富的应用程序。

    2023年11月15日
    1.1K00
  • 如何通过 Oineone 平台自定义视图

    在 Oineone 平台上,自定义视图允许用户替换默认提供的页面布局,以使用自定义页面。本文将指导您如何利用 Oineone 提供的 API 来实现这一点。 默认视图介绍 Oineone 平台提供了多种默认视图,包括: 表单视图 表格视图 表格视图 (左树右表) 详情视图 画廊视图 树视图 每种视图都有其标准的 layout。自定义视图实际上是替换这些默认 layout 的过程。 默认的表单视图 layout <view type="FORM"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="form" slot="form"> <xslot name="fields" slotSupport="pack,field" /> </element> </view> 内嵌的的表单视图 layout <view type="FORM"> <element widget="form" slot="form"> <xslot name="fields" slotSupport="pack,field" /> </element> </view> 默认的表格 <view type="TABLE"> <pack widget="group"> <view type="SEARCH"> <element widget="search" slot="search" slotSupport="field" /> </view> </pack> <pack widget="group" slot="tableGroup"> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="table" slot="table" slotSupport="field"> <element widget="expandColumn" slot="expandRow" /> <xslot name="fields" slotSupport="field" /> <element widget="rowActions" slot="rowActions" slotSupport="action" /> </element> </pack> </view> 内嵌的的表格 <view type="TABLE"> <view type="SEARCH"> <element widget="search" slot="search" slotSupport="field" /> </view> <element widget="actionBar" slot="actionBar" slotSupport="action"> <xslot name="actions" slotSupport="action" /> </element> <element widget="table" slot="table"> <element widget="expandColumn" slot="expandRow" /> <xslot name="fields" slotSupport="field" /> <element widget="rowActions" slot="rowActions" /> </element> </view> 左树右表 <view type="table"> <pack title="" widget="group"> <view type="search"> <element slot="search" widget="search"/> </view> </pack> <pack title="" widget="group"> <pack widget="row" wrap="false"> <pack widget="col" width="257"> <pack title="" widget="group"> <pack widget="col"> <element slot="tree" widget="tree"/> </pack> </pack> </pack> <pack mode="full" widget="col"> <pack widget="row"> <element justify="START" slot="actionBar"…

    2024年4月3日
    1.2K00
  • 【界面设计器】自定义字段组件实战——表格字段组合展示

    阅读之前 此文章为实战教程,已假定你熟悉了【界面设计器】较为完整的【自定义组件】相关内容。 如果在阅读过程中出现的部分概念无法理解,请自行学习相关内容。【前端】文章目录 业务背景 表格中的一列使用多个字段组合展示。 演示内容:表格中存在两列,【编码】和【基础信息】。将【名称】、【创建时间】、【更新时间】在【基础信息】一列展示。 业务分析及实现思路 从需求来看,我们需要实现一个【组合列】组件,并且该组件允许在【表格】视图中使用。由于【组合列】本身也是一个字段,因此这里需要选择需要组合字段中的其中一个字段作为组件切换的基础字段,比如我们可以选择【名称】字段作为基础字段。 在【组合列】组件的属性面板中,我们需要再自定义一个【组合列配置】组件,用来选择需要将哪些字段进行组合,以及为每个组合提供一些基础配置。 这里需要理解一个基本概念,即【组合列】的属性面板是【组合列配置】的【执行页面】。所有组件的属性面板在【执行页面】时都是【表单】视图。 因此我们可以实现一个【组合列配置】组件,并且该组件允许在【表单】视图中使用。其业务类型使用【文本】,我们在保存配置数据时,可以使用JSON数据结构来存储复杂结构。(这里的实现思路并非是最符合协议设定的,但可以满足绝大多数组件场景) 在【组合列配置】组件中,我们可以允许用户添加/移除组合,并且每个组合有两个属性,【标题】和【字段】。 准备工作 此处你应该已经在某个业务模型下,可以完整执行当前模型的全部【增删改查】操作。 业务模型定义 (以下仅展示本文章用到的模型字段,忽略其他无关字段。) 名称 API名称 业务类型 是否多值 长度(单值长度) 编码 code 文本 否 128 名称 name 文本 否 128 创建时间 createDate 日期时间 否 – 更新时间 updateDate 日期时间 否 – 实现页面效果展示 表格视图 创建组件、元件 准备工作完成后,我们需要根据【业务背景】确定【组件】以及【元件】相关信息,并在【界面设计器】中进行创建。 以下操作过程将省略详细步骤,仅展示可能需要确认的关键页面。 创建组合列组件 创建组合列元件 创建组合列配置组件 创建组合列配置元件 设计组合列元件属性面板 创建compositeConfig字段,并切换至【组合配置】组件。 设计组合列配置元件属性面板 启动SDK工程进行组件基本功能开发 PS:这里由于我们创建了两个组件,因此,将SDK分开下载后,然后将组合列配置SDK中的演示代码(kunlun-plugin/src)移动到组合列SDK中,在同一工程中进行开发,最后只需将相关JS文件和CSS文件上传到组合列组件中即可,组合列配置组件可以不进行上传。这里需要注意的是,上传多个包含相同组件功能的JS文件和CSS文件可能在运行时导致无法正常替换、冲突等问题。 (npm相关操作请自行查看SDK工程中内置的README.MD) 开发步骤参考 打开【表格】视图,将【名称】字段的组件切换为【组合列】组件。 在属性面板中看到【组合列配置】组件,并优先实现【组合列配置】组件。这里的属性面板就是【组合列配置】对应的【执行页面】。 当【组合列配置】组件可以按照预先设计的数据结构正确保存compositeConfig属性时,可以在【组合列】组件中的props定义中直接获取该属性,接下来就可以进行【组合列】组件的开发。 代码实现参考 工程结构 typing.ts export interface CompositeConfig { key: string; label?: string; field?: string; value?: string; } CompositeColumnConfig.vue <template> <div class="composite-column-config"> <oio-form v-for="item in list" :data="item" :key="item.key"> <oio-form-item label="标题" name="label"> <oio-input v-model:value="item.label" /> </oio-form-item> <oio-form-item label="字段" name="field"> <a-select class="oio-select" dropdownClassName="oio-select-dropdown" v-model:value="item.field" :options="fields" /> </oio-form-item> <oio-button type="link" @click="() => removeItem(item)">移除</oio-button> </oio-form> <oio-button type="primary" block @click="addItem">添加</oio-button> </div> </template> <script lang="ts"> import { uniqueKeyGenerator } from '@kunlun/dependencies'; import { WidgetInstance } from '@kunlun/ui-designer-dependencies'; import { OioButton, OioForm, OioFormItem, OioInput } from '@kunlun/vue-ui-antd'; import { Select as ASelect } from 'ant-design-vue'; import { computed, defineComponent, PropType, ref, watch } from 'vue'; import { CompositeConfig } from '../../typing'; export default defineComponent({ name: 'CompositeColumnConfig', components: { OioForm, OioFormItem, OioInput, OioButton, ASelect }, props: { currentInstance: { type:…

    2023年11月1日
    1.1K00
  • 如何在Oinone 根据主题实现自定义组件样式

    在页面交互中,样式的变化是前端核心工作之一。本文介绍如何在Oinone平台中根据主题变化自定义组件样式。 介绍 Oinone平台提供了六种不同的主题设置,浅色大主题、浅色中主题、浅色小主题、深色大主题、深色中主题、深色小主题,默认采用浅色中主题。本文旨在指导如何在线或通过代码修改这些主题,以满足个性化需求。 基础知识 Oinone平台的默认主题为浅色中主题,用户可以根据喜好选择以下六种主题中的任何一种: 浅色大主题 浅色中主题 浅色小主题 深色大主题 深色中主题 深色小主题 在线修改主题 用户可以通过进入系统配置应用,并切换到系统风格配置菜单来在线修改主题。选择喜欢的主题并保存即可轻松更换。 代码修改主题 步骤示例 新建theme.ts文件 在项目的src目录下新建一个theme.ts文件。 定义主题变量 在theme.ts文件中定义主题名称和CSS变量,示例中将主色系替换为黑色。 export const themeName = ‘OinoneTheme’; export const themeCssVars = { ‘primary-color’: ‘black’, ‘primary-color-hover’: ‘black’, ‘primary-color-rgb’: ‘0, 0, 0’, ‘primary-color-focus’: ‘black’, ‘primary-color-active’: ‘black’, ‘primary-color-outline’: ‘black’, }; 在main.ts注册 import { registerTheme, VueOioProvider } from ‘@kunlun/dependencies’; // 引入注册主题组件 import { themeName, themeCssVars } from ‘./theme’; // 引入theme.ts registerTheme(themeName, themeCssVars);// 注册 VueOioProvider( { …other config theme: [themeName] // 定义的themeName传入provider中 }, [] ); 4: 刷新页面看效果 注意事项 确保在定义CSS变量时遵循主题设计规范。 正确引入theme.ts文件以避免编译错误。 总结 本文详细介绍了在Oinone平台中修改主题的两种方法:在线修改和代码修改。这些步骤允许开发者和用户根据个人喜好或项目需求,自定义界面的主题风格。

    2024年2月26日
    1.1K00

Leave a Reply

登录后才能评论