【界面设计器】自定义字段组件实战——轮播图

阅读之前

此文章为实战教程,已假定你熟悉了【界面设计器】较为完整的【自定义组件】相关内容。

如果在阅读过程中出现的部分概念无法理解,请自行学习相关内容。【前端】文章目录

业务背景

用户需要从【创建/编辑】页面中上传多张图片,并且在【详情】页面将这多张图片进行【轮播】展示。

业务分析

从需求来看,我们需要实现一个【轮播图】组件,并且该组件允许在【详情】视图中使用。在其他视图中,我们可以直接使用平台内置的【图片】组件,实现基础的编辑和展示功能。

名词解释

  • 业务模型:需要进行可视化管理的存储模型或代理模型。

准备工作

你需要在某个业务模型下创建一个【表格视图】用于查看全部数据,创建【表单视图】用于创建/编辑数据,并创建【详情视图】展示必要的信息。(为了方便起见,你可以在所有视图中仅使用编码和名称两个字段)

你需要将【表格视图】绑定到某个菜单上,并通过【跳转动作】将三个视图进行关联,可以完整执行当前模型的全部【增删改查】操作。

业务模型定义

(以下仅展示本文章用到的模型字段,忽略其他无关字段。)

DemoModel
名称 API名称 业务类型 是否多值 长度(单值长度)
编码 code 文本 128
名称 name 文本 128
轮播图 carouselImages 文本 512

实现页面效果展示

表格视图

image.png

表单视图-创建

image.png

表单视图-编辑

image.png

详情视图

image.png

根据业务背景添加轮播图字段到所有视图

轮播图字段信息:

  • 字段业务类型:文本
  • 多值:是

使用组件:图片

无代码模型

在模型设计器创建轮播图字段,并从【组件库】-【模型】拖放至视图中即可。

PS:这里需要注意的是,在模型设计器中需要切换至专家模式,并确认字段长度为512,否则当URL超长时将无法保存。

低代码模型

与服务端同学确认字段,并从【组件库】-【模型】中拖放至视图中即可。

将上图中的【演示】数据进行【编辑】,并上传三张图片,在【详情视图】查看默认展示效果。

演示图片下载

image.png

创建组件、元件

准备工作完成后,我们需要根据【业务背景】确定【组件】以及【元件】相关信息,并在【界面设计器】中进行创建。

以下操作过程将省略详细步骤,仅展示可能需要确认的关键页面。

创建轮播图组件

image.png

创建轮播图元件

根据业务背景,我们需要根据模型中的字段确定业务类型,在这个场景中,可以使用如下配置。(暂时可以不进行属性面板的设计)

image.png

在【详情视图】中将【轮播图字段】的组件切换为我们新创建的【轮播图组件】

image.png

PS:这里会发现组件变成了【输入框】的样式,这是由于我们没有提供对应元件的代码实现,使得SPI找到了默认组件。

启动SDK工程进行组件基本功能开发

(npm相关操作请自行查看SDK工程中内置的README.MD)

Carousel.vue
<template>
  <a-carousel class="carousel" effect="fade" autoplay>
    <div class="carousel-item" v-for="image in images" :key="image">
      <img :src="image" :alt="image" />
    </div>
  </a-carousel>
</template>
<script lang="ts">
import { Carousel as ACarousel } from 'ant-design-vue';
import { computed, defineComponent, PropType } from 'vue';

export default defineComponent({
  name: 'Carousel',
  components: {
    ACarousel
  },
  props: {
    value: {
      type: Array as PropType<string[]>
    }
  },
  setup(props) {
    const images = computed(() => props.value || []);

    return {
      images
    };
  }
});
</script>
<style lang="scss">
.carousel {
  .slick-slide {
    height: 160px;

    & > div,
    .carousel-item {
      width: 100%;
      height: 100%;
    }

    img {
      max-width: 100%;
      max-height: 100%;
      margin: auto;
    }
  }
}
</style>
效果展示

开发完成后,我们将重新打包生成的JS文件和CSS文件在【界面设计器】的【低无一体】进行上传,就可以在【设计器环境】中正常使用了。

image.png

设计轮播图的属性面板

通过我们使用的a-carousel组件,我们发现组件中提供了很多【属性】或【功能】可以进行配置,比如是否自动切换(autoplay)、面板指示点位置(dotPosition)、是否显示面板指示点(dots)等。在这里我们将对这三个属性的配置方式进行演示,其他更多属性可以自行设计并开发。

我们可以在【界面设计器】的【属性面板设计】中根据这三个属性的字段类型确定以下信息:

功能 API名称 业务类型 选用组件 可选项
是否自动切换 autoplay 布尔 开关 -
是否显示面板指示点 dots 布尔 开关 -
面板指示点位置 dotPosition 数据字典 下拉单选 上方(top)、下方(bottom)、左侧(left)、右侧(right)

确定了这些信息后,我们在【属性面板设计】中拖入对应组件,并创建【指定API名称】的字段。

PS:数据字典类型的字段需要先在模型设计器中创建对应的数据字典,才能创建该字段。由于设计器本身的依赖关系,建议将数据字典创建在【资源】模块中,这样才可以在设计器被选中。

数据字典

image.png

image.png

PS:前端获取的值为【API名称】,并非【字典项值】。

属性面板设计

image.png

在SDK中为组件新增的属性补充代码实现

typing.ts
export enum CarouselPosition {
  top = 'top',
  bottom = 'bottom',
  left = 'left',
  right = 'right'
}
DetailStringMultiCarouselFieldWidget.ts
import { BooleanHelper, FormFieldWidget, ModelFieldType, SPI, ViewType, Widget } from '@kunlun/dependencies';
import Carousel from './Carousel.vue';
import { CarouselPosition } from './typing';

@SPI.ClassFactory(
  FormFieldWidget.Token({
    viewType: ViewType.Detail,
    ttype: ModelFieldType.String,
    widget: 'Carousel',
    multi: true
  })
)
export class DetailStringMultiCarouselFieldWidget extends FormFieldWidget {
  public initialize(props) {
    super.initialize(props);
    this.setComponent(Carousel);
    return this;
  }

  @Widget.Reactive()
  protected get autoplay() {
    return BooleanHelper.toBoolean(this.getDsl().autoplay);
  }

  @Widget.Reactive()
  protected get dots() {
    return BooleanHelper.toBoolean(this.getDsl().dots);
  }

  @Widget.Reactive()
  protected get dotPosition(): CarouselPosition | undefined {
    return this.getDsl().dotPosition;
  }
}
Carousel.vue
<template>
  <a-carousel class="carousel" effect="fade" :autoplay="autoplay" :dots="dots" :dotPosition="dotPosition">
    <div class="carousel-item" v-for="image in images" :key="image">
      <img :src="image" :alt="image" />
    </div>
  </a-carousel>
</template>
<script lang="ts">
import { Carousel as ACarousel } from 'ant-design-vue';
import { computed, defineComponent, PropType } from 'vue';
import { CarouselPosition } from './typing';

export default defineComponent({
  name: 'Carousel',
  components: {
    ACarousel
  },
  props: {
    value: {
      type: Array as PropType<string[]>
    },
    autoplay: {
      type: Boolean
    },
    dots: {
      type: Boolean
    },
    dotPosition: {
      type: String as PropType<CarouselPosition>
    }
  },
  setup(props) {
    const images = computed(() => props.value || []);

    const dotPosition = computed(() => props.dotPosition?.toLowerCase());

    return {
      images,
      dotPosition
    };
  }
});
</script>
<style lang="scss">
.carousel.ant-carousel {
  .slick-slide,
  .slick-vertical {
    height: 160px;
  }

  .slick-slide {
    & > div,
    .carousel-item {
      width: 100%;
      height: 100%;
    }

    img {
      max-width: 100%;
      max-height: 100%;
      margin: auto;
    }
  }
}
</style>

开发完成后,我们将重新打包生成的JS文件和CSS文件在【界面设计器】的【低无一体】进行上传,就可以在【设计器环境】中正常使用了。

设计组件优化

在执行到以上步骤之后,我们发现执行页面和设计页面的属性面板都可以正常运行,美中不足的是,我们无法在设计器直观看到预览效果。为了解决这一问题,我们需要对设计组件进行相关的优化。

细心的同学可能也会发现,我们在组件中对高度的设定是160px,这个设置会导致用户无法根据需求进行定制。不仅如此,由于宽度属性未进行配置,用户也无法根据需求调整宽度。

为了解决上述问题,我们可以将属性面板稍作调整。

宽度使用内置的数据字典类型的宽度即可,高度需要我们新建一个高度(height)的整数字段,并添加后缀提示用户高度的单位。

效果如下图所示:

image.png

接下来,我们仅需实现【预览效果】和【高度】属性即可,内置的【宽度】属性是通过外部控制的,组件本身无需关心。

实现思路:

  • 由于设计器的预览功能移除了Class Component(ts)组件的相关功能,而是直接将属性面板的值传递到Vue组件中,因此,我们需要在Vue组件中判断当前组件是否在设计器的预览环境中,并且根据这个判断提供相应的预览效果。我们可以使用代码示例中的isDesignComponent属性,来实现这一功能。
  • 高度在用户输入时为【整数】,因此是没有单位的,可以使用平台内置的StyleHelper#px方法进行转换。
Carousel.vue
<template>
  <a-carousel class="carousel" effect="fade" :autoplay="autoplay" :dots="dots" :dotPosition="dotPosition">
    <template v-if="isDesignComponent">
      <div class="carousel-item carousel-item-demo"><h3>1</h3></div>
      <div class="carousel-item carousel-item-demo"><h3>2</h3></div>
      <div class="carousel-item carousel-item-demo"><h3>3</h3></div>
    </template>
    <template v-else>
      <div class="carousel-item" v-for="image in images" :key="image">
        <img :src="image" :alt="image" />
      </div>
    </template>
  </a-carousel>
</template>
<script lang="ts">
import { StyleHelper } from '@kunlun/dependencies';
import { Carousel as ACarousel } from 'ant-design-vue';
import { computed, defineComponent, PropType } from 'vue';
import { CarouselPosition } from './typing';

export default defineComponent({
  name: 'Carousel',
  components: {
    ACarousel
  },
  props: {
    value: {
      type: Array as PropType<string[]>
    },
    autoplay: {
      type: Boolean
    },
    dots: {
      type: Boolean
    },
    dotPosition: {
      type: String as PropType<CarouselPosition>
    },
    height: {
      type: [Number, String]
    },
    isDesignComponent: {
      type: Boolean,
      default: true
    }
  },
  setup(props) {
    const images = computed(() => props.value || []);

    const dotPosition = computed(() => props.dotPosition?.toLowerCase());

    const height = computed(() => StyleHelper.px(props.height) || '160px');

    return {
      images,
      dotPosition,
      height
    };
  }
});
</script>
<style lang="scss">
.carousel.ant-carousel {
  .slick-slide,
  .slick-vertical {
    height: v-bind(height);
  }

  .slick-slide {
    & > div,
    .carousel-item {
      width: 100%;
      height: 100%;
    }

    img {
      max-width: 100%;
      max-height: 100%;
      margin: auto;
    }
  }

  .carousel-item-demo {
    display: flex !important;
    align-items: center;
    justify-content: center;
    background-color: #364d79;

    h3 {
      color: #ffffff;
    }
  }
}
</style>
DetailStringMultiCarouselFieldWidget.ts
import { BooleanHelper, FormFieldWidget, ModelFieldType, SPI, ViewType, Widget } from '@kunlun/dependencies';
import Carousel from './Carousel.vue';
import { CarouselPosition } from './typing';

@SPI.ClassFactory(
  FormFieldWidget.Token({
    viewType: ViewType.Detail,
    ttype: ModelFieldType.String,
    widget: 'Carousel',
    multi: true
  })
)
export class DetailStringMultiCarouselFieldWidget extends FormFieldWidget {
  public initialize(props) {
    super.initialize(props);
    this.setComponent(Carousel);
    return this;
  }

  @Widget.Reactive()
  protected get autoplay() {
    return BooleanHelper.toBoolean(this.getDsl().autoplay);
  }

  @Widget.Reactive()
  protected get dots() {
    return BooleanHelper.toBoolean(this.getDsl().dots);
  }

  @Widget.Reactive()
  protected get dotPosition(): CarouselPosition | undefined {
    return this.getDsl().dotPosition;
  }

  @Widget.Reactive()
  protected get height(): number | string | undefined {
    return this.getDsl().height;
  }

  @Widget.Reactive()
  protected get isDesignComponent() {
    return false;
  }
}

开发完成后,我们将重新打包生成的JS文件和CSS文件在【界面设计器】的【低无一体】进行上传,就可以在【设计器环境】中正常使用了。

除了上述我们演示的功能实现外,其实轮播图组件还可以有其他更多的功能。比如:轮播图中的图片展示方式可以是拉伸、平铺、等比缩放等,轮播图分页样式,轮播图是否展示左右翻页按钮以及翻页按钮的样式,轮播动画效果等等。

结语

至此,我们已经基本完成了一个简单的轮播图组件。

从轮播图组件的实现来看,对我们传统开发思维提出了一些挑战。

在传统组件开发中,我们开发的一个一个Vue组件都是提供给其他开发人员使用的,甚至绝大多数组件是由于单个组件的复杂性进行拆分的一个一个小组件。

在传统开发思维中,我们很难感受到当一个组件具备用户输入能力时,它所展示的最终效果。甚至在某些场景中,用户输入的结果并非是我们所能预知的。

对于低代码组件而言,其使得用户对组件可以有一定程度的输入能力。正是由于存在这样的差异,我们更需要站在用户角度去思考组件该通过怎样的输入得到怎样的输出

从结果上来看,低代码组件为用户提供的输入能力可以使得组件应用的场景更加广泛,再结合界面设计器的在线设计能力,可以促使我们在开发组件时使其具有更高的复用能力。

Oinone社区 作者:数式-海波原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/55.html

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

(0)
数式-海波的头像数式-海波数式管理员
上一篇 2023年6月20日 pm4:07
下一篇 2023年11月2日 pm1:58

相关推荐

  • 前端自定义组件之多页面步骤条

    本文将讲解如何通过自定义,实现多页面的步骤条组件。其中每个步骤的元素里都对应界面设计器的一个页面。以下是代码实现和原理分析。 代码实现 NextStepWidget 多页面步骤条 ts 组件 import { CallChaining, createRuntimeContextByView, customMutation, customQuery, RuntimeView, SPI, ViewCache, Widget, DefaultTabsWidget, BasePackWidget } from '@oinone/kunlun-dependencies'; import { isEmpty } from 'lodash-es'; import { MyMetadataViewWidget } from './MyMetadataViewWidget'; import NextStep from './NextStep.vue'; import { IStepConfig, StepDirection } from './type'; @SPI.ClassFactory(BasePackWidget.Token({ widget: 'NextStep' })) export class NextStepWidget extends DefaultTabsWidget { public initialize(props) { this.titles = props.template?.widgets?.map((item) => item.title) || []; props.template && (props.template.widgets = []); super.initialize(props); this.setComponent(NextStep); return this; } @Widget.Reactive() public get invisible() { return false; } // 配置的每一步名称 @Widget.Reactive() public titles = []; // region 上一步下一步配置 // 步骤配置,切换的顺序就是数组的顺序,模型没有限制 @Widget.Reactive() public get stepJsonConfig() { let data = JSON.parse( this.getDsl().stepJsonConfig || '[{"model":"resource.ResourceCountry","viewName":"国家form"},{"model":"resource.ResourceProvince","viewName":"省form"},{"model":"resource.ResourceCity","viewName":"市form"}]' ); return data as IStepConfig[]; } // 切换上一步下一步 @Widget.Method() public async onStepChange(stepDirection: StepDirection) { // 没有激活的,说明是初始化,取第一步 if (!this.activeStepKey) { const step = this.stepJsonConfig[0]; if (step) { this.activeStepKey = `${step.model}_${step.viewName}`; await this.initStepView(step); } return; } // 获取当前步骤的索引 if (this.currentActiveKeyIndex > -1) { await this.onSave(); // 获取下一步索引 const nextStepIndex = stepDirection === StepDirection.NEXT ? this.currentActiveKeyIndex + 1 : this.currentActiveKeyIndex – 1; // 在索引范围内,则渲染视图 if (nextStepIndex >= 0 && nextStepIndex < this.stepJsonConfig.length) { const nextStep = this.stepJsonConfig[nextStepIndex];…

    2025年7月21日
    72900
  • 前端6.2.x升级指南

    升级背景 从 6.2.x 版本开始,平台底层核心代码已全面开源(设计器相关代码除外),本次升级涉及包名变更和配置调整,以下是详细的升级步骤 1. 更新 .npmrc 配置 修改当前项目根目录 .npmrc 文件,内容如下: registry=https://registry.npmmirror.com/ @oinone:registry=http://nexus.shushi.pro/repository/kunlun/ @kunlun:registry=http://nexus.shushi.pro/repository/kunlun/ shamefully-hoist=true legacy-peer-deps=true link-workspace-packages = true prefer-workspace-packages = true recursive-install = true lockfile=true 2. 包名变更 以前的包是 @kunlun/xxxx,现在的包名是@oinone/kunlun开头,所以需要全部替换修改。 旧包名 新包名 @kunlun/dependencies @oinone/kunlun-dependencies @kunlun/vue-ui-antd @oinone/kunlun-vue-ui-antd 3. 升级依赖版本 修改所有 package.json 中更新所有平台相关依赖: – "@kunlun/dependencies": "~5.7.0" + "@oinone/kunlun-dependencies": "~6.2.0" boot工程的package.json新增devDependencies依赖 "devDependencies": { "@types/lodash": "4.14.182", "@types/lodash-es": "4.17.6", ….. } 4. 更新代码引用 全局搜索并替换代码中的所有 @kunlun/ 为 @oinone/kunlun- 完整的 main.ts import 'ant-design-vue/dist/antd.min.css'; import 'element-plus/dist/index.css'; import '@oinone/kunlun-vue-ui-antd/dist/oinone-kunlun-vue-ui-antd.css'; import '@oinone/kunlun-vue-ui-el/dist/oinone-kunlun-vue-ui-el.css'; import '@oinone/kunlun-designer-common/dist/oinone-kunlun-designer-common.css'; import '@oinone/kunlun-model-designer/dist/oinone-kunlun-model-designer.css'; import '@oinone/kunlun-workflow-designer/dist/oinone-kunlun-workflow-designer.css'; import '@oinone/kunlun-workflow/dist/oinone-kunlun-workflow.css'; import '@oinone/kunlun-data-designer/dist/oinone-kunlun-data-designer.css'; import '@oinone/kunlun-microflow-designer/dist/oinone-kunlun-microflow-designer.css'; import 'reflect-metadata'; import ElementPlus from 'element-plus'; import { App } from 'vue'; import { VueOioProvider, RuntimeContextManager } from '@oinone/kunlun-dependencies'; // 设计器 import '@oinone/kunlun-ui-designer-dependencies'; import '@oinone/kunlun-print-designer-dependencies'; import '@oinone/kunlun-workflow'; import '@oinone/kunlun-workflow-designer'; import '@oinone/kunlun-model-designer'; import '@oinone/kunlun-data-designer'; import '@oinone/kunlun-data-designer-open-pc'; import '@oinone/kunlun-eip-dependencies'; import '@oinone/kunlun-ai-dependencies'; import '@oinone/kunlun-microflow-designer'; import '@oinone/kunlun-designer-common-ee'; // 下面三个依赖是当前工程的包,请根据实际场景修改 import '@ss/oinone'; import '@ss/admin-widget'; import '@ss/project'; VueOioProvider( { browser: { title: 'Oinone – 构你想象!', favicon: 'https://pamirs.oss-cn-hangzhou.aliyuncs.com/pamirs/image/default_favicon.ico' } }, [ () => { /// 获取当前vue实例 const app = RuntimeContextManager.createOrReplace().frameworkInstance as App; } ] ); 当配置全部修改完成后,重写安装依赖 # 清理旧依赖 pnpm clean # 安装新依赖 pnpm install

    2025年6月17日
    53400
  • 上下文在字段和动作中的应用

    上下文在字段和动作中的应用 在业务场景中,常常需要在打开弹窗或跳转到新页面时携带当前页面数据。此时,我们需要配置相关「动作」中的上下文信息。 在 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.4K10
  • OioNotification 通知提醒框

    全局展示通知提醒信息。 何时使用 在系统四个角显示通知提醒信息。经常用于以下情况: 较为复杂的通知内容。 带有交互的通知,给出用户下一步的行动点。 系统主动推送。 API OioNotification.success(title,message, config) OioNotification.error(title,message, config) OioNotification.info(title,message, config) OioNotification.warning(title,message, config) config 参数如下: 参数 说明 类型 默认值 版本 duration 默认 3 秒后自动关闭 number 3 class 自定义 CSS class string –

    2023年12月18日
    91100
  • 如何实现页面间的跳转

    介绍 在日常的业务中,我们经常需要在多个模型的页面之间跳转,例如从商品的行可以直接点击链接跳转到类目详情,还有查看该订单发起的售后单列表,这里将给大家展示如何在oinone中如何实现这些功能。 方法一、通过界面设计器的无代码能力配置 表格行跳转到表单页/详情页 拖入一个跳转动作到表格行,保存动作后,在左侧的动作属性面板底部有个请求配置,里面的上下文属性就是配置跳转参数的地方,点击添加按钮可以增加一行参数 点击添加按钮后,可以看到新增了一行,行内有2个输入框,左侧输入框为目标视图模型的字段,右侧输入框为当前视图模型的表达式 注意 表达式中activeRecord关键字代表当前行的数据对象 “上下文”相关知识点 当前页面的模型和跳转后的页面模型相同的情况下,会字段带上当前行数据的id作为路由参数 上下文是从当前页面跳转到下个页面带的自定义参数 上下文会作为跳转后的页面数据加载函数的入参,后端的该函数需要根据该条件查询到数据返回给前端,典型的例子就是编辑页,根据id查询对象的其他字段信息返回 跳转后页面的数据加载函数可以在动作场景的时候选择加载函数,也可以在页面的加载函数处设置 方法二、通过低代码方式在自定义代码中调用 oinone提供了内置函数executeViewAction实现该功能 import { DefaultComparisonOperator, executeViewAction, QueryExpression, RuntimeViewAction, ViewActionTarget, ViewType } from '@kunlun/dependencies'; export class JumpActionWidget { protected goToObjectView() { executeViewAction( { viewType: ViewType.Form, moduleName: 'resource', model: 'resource.ResourceCountry', name: 'redirectUpdatePage', target: ViewActionTarget.Router } as RuntimeViewAction, undefined, undefined, { // 此处为id参数,目前只有表单和详情页需要 id: '12223', // 此处为上下文参数,context内对象的key是目标页面需要传递的默认值 context: JSON.stringify({code: 'xxx'}), // 此处为跳转后左侧菜单展开选中的配置 menu: JSON.stringify({"selectedKeys":["国家"],"openKeys":["地址库","地区"]}) } ); } protected goToListView() { const searchConditions: QueryExpression[] = []; searchConditions.push({ leftValue: ['countryCode'], // 查询条件的字段 operator: DefaultComparisonOperator.EQUAL, right: 'CN' // 字段的值 }); executeViewAction( { viewType: ViewType.Table, moduleName: 'resource', model: 'resource.ResourceCity', name: 'resource#市', target: ViewActionTarget.OpenWindow } as RuntimeViewAction, undefined, undefined, { // searchConditions相当于domain,不会随页面搜索项重置动作一起被清空 searchConditions: encodeURIComponent(JSON.stringify(searchConditions)), // searchBody的字段会填充搜索区域的字段组件,会随页面搜索项重置动作一起被清空 searchBody: JSON.stringify({code: 'CN'}), menu: JSON.stringify({"selectedKeys":["国家"],"openKeys":["地址库","地区"]}) } ); } } 扩展知识点 为什么executeViewAction跳转到的新页面不是入参的moduleName属性对应的模块? 答:跳转后所在的模块优先级为: 第一个入参的resModuleName属性对应的模块 执行executeViewAction时所在的模块 第一个入参的moduleName属性对应的模块 如何快速获取选中菜单的值? 答:先通过页面菜单手动打开页面,然后在浏览器自带调试工具的控制台执行decodeURIComponent(location.href),其中的menu参数就是我们需要的值

    2024年5月13日
    2.8K00

Leave a Reply

登录后才能评论