• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Views:Table Row Copy Functionality


Ⅰ. Scenario Overview

After clicking the Add Button, the table displays an empty row without business data, and inline editing is required.

Ⅱ. Solution

(I) Add a new copyTable component in the layout directory; the component code is as follows

import { BaseElementWidget, SPI, TableWidget, Widget } from '@kunlun/dependencies';
import { OioNotification } from '@kunlun/vue-ui-antd';

@SPI.ClassFactory(BaseElementWidget.Token({ widget: 'copy-table-row' }))
  export class CopyTableWidget extends TableWidget {
    @Widget.BehaviorSubContext(Symbol("$$TABLE_COPY_CB"), {})
    private tableCopySub;

    @Widget.BehaviorSubContext(Symbol("$$TABLE_DELETE_CB"))
    private tableDeleteSub;

    @Widget.Reactive()
    @Widget.Provide()
    protected get editorMode(): any {
      return 'manual'
    }

    public async copyRowData(row,currentRow) {
      // Get the vxetable instance
      const tableRef = this.getTableInstance()!.getOrigin();
      if (tableRef) {
        // How to handle copied unsaved data?
        const insertData = tableRef.getInsertRecords();
        if(insertData.length > 0){
          OioNotification.warning("Warning","Please check unsaved data!")
          return;
        }

        const { row: newRow } = await tableRef.insertAt(row,currentRow)
        // Insert a piece of data and trigger verification; the field name can be replaced
        await tableRef.setEditCell(newRow, 'city')
      }
    }

    public async deleteRowData(row) {
      // Get the vxetable instance
      const tableRef = this.getTableInstance()!.getOrigin();
      if (tableRef) {
        // How to handle copied unsaved data?
        console.log(row, 'remove row')
        tableRef.remove(row)
        // Insert a piece of data and trigger verification
      }
    }

    async mounted() {
      super.mounted();
      this.tableCopySub.subject.next({copyCb: (row,currentRow) => this.copyRowData(row,currentRow)})
      this.tableDeleteSub.subject.next({deleteCb: (row) => this.deleteRowData(row)})
    }
  }

(II) Override the Add Button or Copy Row Button in the action directory; the code is as follows

import {ActionWidget, ClickResult, ReturnPromise, SPI, Widget} from "@kunlun/dependencies";

@SPI.ClassFactory(
  ActionWidget.Token({
    model: 'resource.k2.Model0000001211', // Replace with the corresponding model
    name: 'uiView57c25f66fac9439089d590a4ac47f027' // Replace with the name of the corresponding action
  })
)
  export class CopyRow extends ActionWidget{
    @Widget.BehaviorSubContext(Symbol("$$TABLE_COPY_CB"))
    private tableCopySub;

    private tableCopyCb;

    @Widget.Method()
    public clickAction(): ReturnPromise<ClickResult> {
      // Copy a row based on a specific piece of data; the button is inline
      // let data = JSON.parse(JSON.stringify(this.activeRecords?.[0]));
      // Delete the ID when copying the row
      // if(data) {
      //   delete data.id
      //   delete  data['_X_ROW_KEY']
      // }
      // console.log(data, 'datatatatat')
      // this.tableCopyCb(data,this.activeRecords?.[0])

      // Global addition without default data
      this.tableCopyCb({},null)
    }

    mounted() {
      super.mounted()
      this.tableCopySub.subscribe((value) => {
        if(value) {
          // debugger
          this.tableCopyCb = value.copyCb
        }
      })
    }
  }

(III) Replace the corresponding table layout

// Replace the model and action in the second input parameter
const registerGlobalTableLayout = () => {
  return registerLayout(`<view type="TABLE">
    <pack widget="group">
        <view type="SEARCH">
            <element widget="search" slot="search" slotSupport="field" />
        </view>
    </pack>
    <element widget="actionBar" slot="actionBar" slotSupport="action">
        <xslot name="actions" slotSupport="action" />
    </element>
    <pack widget="group" slot="tableGroup">
        <element widget="copy-table-row" slot="table" slotSupport="field">
            <element widget="expandColumn" slot="expandRow" />
            <xslot name="fields" slotSupport="field" />
            <element widget="rowActions" slot="rowActions" slotSupport="action" />
        </element>
    </pack>
</view>`, { viewType: ViewType.Table, model: 'resource.k2.Model0000001211' })
}

registerGlobalTableLayout()

(IV) Supplementary Notes

  1. The actions after adding an empty row can be configured to show or hide based on inline data. For example, the presence or absence of an ID determines whether it is set to "Edit" or "Save".
  2. How to enable inline editing after addition? You can enter the UI Designer, select the table field, enable inline editing, and the newly added row will have inline editing by default.

I’ve completed the translation of the Chinese content while retaining the original document structure and code blocks, and used standard Internet/frontend development terminology. Do you need me to further sort out a glossary of key Internet terminology used in this document for easier reference in subsequent development?

Edit this page
Last Updated:1/14/26, 8:45 AM
Prev
Views:Table Column Footer Statistics
Next
Route Extension:Adding New Routes, such as Overriding the Default Login Page
默认页脚
Copyright © 2026 Mr.Hope