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

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

相关推荐
2401_882727577 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
lsjweiyi11 小时前
极简AI工具箱网站开源啦!
opencv·开源·微信支付·支付宝支付·百度ai·极简ai工具箱·ai图像处理
开源社13 小时前
一场开源视角的AI会议即将在南京举办
人工智能·开源
FreeIPCC13 小时前
谈一下开源生态对 AI人工智能大模型的促进作用
大数据·人工智能·机器人·开源
海害嗨13 小时前
阿里巴巴官方「SpringCloudAlibaba全彩学习手册」限时开源!
学习·开源
生命是有光的13 小时前
【开源风云】从若依系列脚手架汲取编程之道(八)
开源
HuggingFace14 小时前
Halo 正式开源: 使用可穿戴设备进行开源健康追踪
开源·健康追踪
时光追逐者18 小时前
.NET 9 中 LINQ 新增功能实操
开发语言·开源·c#·.net·.netcore·linq·微软技术
檀越剑指大厂21 小时前
Linux本地部署开源项目OpenHands基于AI的软件开发代理平台及公网访问
linux·人工智能·开源
胜天半子_王二_王半仙1 天前
c++源码阅读__ThreadPool__正文阅读
开发语言·c++·开源