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...

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

相关推荐
pursue.dreams11 分钟前
腾讯开源智能体框架Youtu-agent全解析:特性、架构与实战指南
开源·智能体·youtuagent
先做个垃圾出来………12 分钟前
Dify开源AI框架介绍
人工智能·开源
ajassi20007 小时前
开源 C++ QT Widget 开发(十五)多媒体--音频播放
linux·c++·qt·开源
兆龙电子单片机设计7 小时前
【STM32项目开源】STM32单片机智能恒温箱控制系统
stm32·单片机·物联网·开源·毕业设计
大写-凌祁7 小时前
零基础入门深度学习:从理论到实战,GitHub+开源资源全指南(2025最新版)
人工智能·深度学习·开源·github
2501_915918418 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
虎头金猫13 小时前
如何在Linux上使用Docker在本地部署开源PDF工具Stirling PDF:StirlingPDF+cpolar让专业操作像在线文档一样简单
linux·运维·ubuntu·docker·pdf·开源·centos
三花AI13 小时前
腾讯开源 HunyuanImage-2.1:17B 参数文生图模型原生支持 2K 高清
开源
算家计算14 小时前
面壁智能开源多模态大模型——MiniCPM-V 4.5本地部署教程:8B参数开启多模态“高刷”时代!
人工智能·开源
yinmaisoft16 小时前
当低代码遇上AI,有趣,实在有趣
android·人工智能·低代码·开发工具·rxjava