LowcodeEngine实战-resetsetter实现

背景

  1. 在设计器中调整物料属性时,鉴于组件及其属性数量庞大,难以一一牢记每个属性的默认值,因此,为每个属性增设一个重置按钮变得至关重要。这一改进将极大地方便用户在需要时快速将属性恢复到初始状态,从而提升操作效率和用户体验。
  2. 物料的属性没有设置默认值,在设计器中不修改保存后schema中是没有这一项属性的。然而一旦在设计器中修改了该属性无论怎么操作也不能回到schema中没有该项属性的时候。

目的

  1. 简化属性配置提高开发效率(针对背景1)
  2. 提供一个删除schema中物料属性的方案(针对背景2)

方案

  1. 在ext仓库中开发一个resetsetter来支持重置当前物料属性到默认状态(defaultValue/initialValue)。
  2. 在物料描述中使用该setter。
  3. 在engine中添加一个supportResetGlobally属性,设置所有属性支持重置。

效果

有resetsetter,两个setter

有resetsetter并超过两个setter

实现

ext

新建reset-setter

在lowcode-engine-ext仓库的setter目录下新建一个reset-setter目录及下级的index.tsxhe resetIcon.tsx 这个setter中没有什么逻辑。

修改mixed-setter

主要是修改render()函数中对于resetsetter的处理逻辑。点击resetsetter时重置属性 在有resetsetter的情况下:

  • 有两个setter:resetsetter在最后
  • 有三个setter时:有variable和reset setter时,最后一个位置放resetsetter,倒数第二个放variableSetter。如果没有variableSetter第二个位置就是switchAction。
  • 超过三个:同三个setter

resetsetter处理逻辑实现

tsx 复制代码
private contentsFromPolyfill2() {
  const { field } = this.props;

  const setterNum = this.setters.length;
  if (setterNum < 4) {
    return this.handleSettersLessThanFour(field, setterNum);
  } else {
    return this.handleSettersGreaterThanThree(field);
  }

}
handleSettersLessThanFour(field: SettingField, setterNum: number) {
  if (setterNum === 1) {
    // return { actions: this.handleResetSetterAction() }
  }
  if (setterNum === 2) {
    return this.handleTwoSetters(field);
  }
  if (setterNum === 3) {
    return this.handleThreeSetters(field)
  }
}

handleTwoSetters(field: SettingField) {
  const otherSetter = this.setters.find((item) => item.name !== 'ResetSetter')!;
  if (otherSetter.name === 'VariableSetter') {
    return {
      setterContent: this.renderVariableSetterContent(field),
      actions: this.handleResetSetterAction(),
    }
  }
  return {
    setterContent: this.renderCurrentSetter(otherSetter, {
      value: field.getMockOrValue(),
    }),
    actions: this.handleResetSetterAction(),
  }
}
  // 最后一个放resetsetter,如果有variableSetter,则放在第二个位置,其他的放在第一个位置。如果没有variableSetter则使用swtich切换操作
  handleThreeSetters(field: SettingField) {
    if (this.setters.some(setter => setter.name === 'VariableSetter') && this.setters.some(setter => setter.name === 'ResetSetter')) {
      // 其他放第一个,VariableSetter放第二个,reset放到最后
      const otherSetter = this.setters.find((item) => (item.name !== 'VariableSetter') && (item.name !== 'ResetSetter'))
      const otherSetterContent = this.renderCurrentSetter(otherSetter, {
        value: field.getMockOrValue(),
      });
      // VariableSetter
      const variableSetterComponent = getSetter('VariableSetter')?.component as any;
      const tipContent = field.isUseVariable()
      ? intlNode('Binded: {expr}', { expr: field.getValue()?.value })
      : intlNode('Variable Binding');
      const variableSetterContent = (
          <Title
          className={field.isUseVariable() ? 'variable-binded' : ''}
          title={{
            icon: <IconVariable size={24} />,
            tip: tipContent,
          }}
          onClick={() => {
            variableSetterComponent.show({ prop: field });
          }}
        />
      );
      return {
        setterContent: otherSetterContent,
        actions: (<>{variableSetterContent}{this.handleResetSetterAction()}</>),
      }
    } else {
      // switch+reset
      const currentSetter =
        !this.used && field.isUseVariable()
          ? this.setters.find((item) => item.name === 'VariableSetter')
          : this.getCurrentSetter();
      return {
        setterContent: this.renderCurrentSetter(currentSetter),
        actions: (<>{this.renderSwitchAction(currentSetter)}{this.handleResetSetterAction()}</>)
      }
    }
  }

  handleSettersGreaterThanThree(field: SettingField) {
    let setterContent: ReactNode;
    const currentSetter =
    !this.used && field.isUseVariable()
      ? this.setters.find((item) => item.name === 'VariableSetter')
      : this.getCurrentSetter();
      if (currentSetter?.name === 'VariableSetter') {
        const variableSetterComponent = getSetter('VariableSetter')?.component as any;
        setterContent = (
          <a
            onClick={() => {
              variableSetterComponent.show({ prop: field });
            }}
          >
            {intlNode('Binded: {expr}', { expr: field.getValue()?.value })}
          </a>
        );
      } else {
        setterContent = this.renderCurrentSetter(currentSetter);
      }
      return {
        setterContent,
        actions: (<>{this.renderSwitchAction(currentSetter)}{this.handleResetSetterAction()}</>)
      }
  }

重置值处理

tsx 复制代码
  private handleResetSetterAction() {
    return (<Title
      title={{
        icon: <ResetIcon size={24} />,
        tip: intlNode('Reset Attribute'),
      }}
      onClick={() => this.resetClickHandler()}
    />)
  }

  resetClickHandler() {
    const { onChange, initialValue, field } = this.props;
    let newValue = initialValue;
    if (field.isUseVariable() || this.used === 'VariableSetter') {
      const fieldValue = field.getValue();
      const value =
        Object.prototype.toString.call(fieldValue) === '[object Object]'
          ? fieldValue.mock
          : fieldValue;
      // 清除变量绑定
      field.setValue(value);
      // 清除标记
      this.used = undefined;
      newValue = newValue??value;
    }
    // fixme 属性为children默认使用StringSetter并且不配置defaultValue时,onChange(null)画布不会更新,so做此处理。例如antd物料的button组件
    if (this.used === 'StringSetter') {
      newValue = newValue?? '';
    }
    this.used = undefined;
    onChange(newValue)
  }

engine

引擎中主要是处理supportResetGlobally属性。主要修改settings-pane.tsx文件的get setterInfo()。

物料

在setter中添加Resetsetter.

demo

在init函数中添加supportResetGlobally: true,开启全局resetsetter

代码仓库

ext:github.com/ChiZng/lowc...

engine:github.com/ChiZng/lowc...

本文正在参加阿里低代码引擎征文活动

相关推荐
FIT2CLOUD飞致云2 小时前
测试管理新增视图与高级搜索功能,测试计划支持一键生成缺陷详情,MeterSphere开源持续测试工具v3.3版本发布
开源·接口测试·metersphere·团队协作·持续测试·测试管理
杨荧4 小时前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
布列瑟农的星空17 小时前
低代码平台实践——代码编辑器
低代码
杨荧18 小时前
【JAVA开源】基于Vue和SpringBoot的水果购物网站
java·开发语言·vue.js·spring boot·spring cloud·开源
colorknight20 小时前
1.2.3 HuggingFists安装说明-MacOS安装
人工智能·低代码·macos·huggingface·数据科学·ai agent
x-cmd21 小时前
[241005] 14 款最佳免费开源图像处理库 | PostgreSQL 17 正式发布
数据库·图像处理·sql·安全·postgresql·开源·json
customer081 天前
【开源免费】基于SpringBoot+Vue.JS洗衣店订单管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
杨荧1 天前
【JAVA开源】基于Vue和SpringBoot的周边产品销售网站
java·开发语言·vue.js·spring boot·spring cloud·开源
时光追逐者1 天前
WaterCloud:一套基于.NET 8.0 + LayUI的快速开发框架,完全开源免费!
前端·microsoft·开源·c#·.net·layui·.netcore
customer082 天前
【开源免费】基于SpringBoot+Vue.JS美容院管理系统(JAVA毕业设计)
android·java·vue.js·spring boot·spring cloud·开源