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

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

相关推荐
m4Rk_2 小时前
【论文阅读】Agent 记忆机制(67):MemPO——用记忆级信用分配训练 Agent 主动管理长程上下文
论文阅读·人工智能·学习·开源·github
hoaxxcj2 小时前
DeepSeek Harness 本地部署与第三方插件排障实录:从 fetch failed 到 preset not found
人工智能·windows·开源·ai agent·deepseek
parksben3 小时前
OpenSider:让浏览器驱动 Agent
开源·github·agent
程序员老赵3 小时前
Docker 部署填鸭表单完整教程:搭建私有化问卷与表单收集平台
前端·docker·开源
Rudon滨海渔村4 小时前
免费开源的Web版windows画图软件 - 简单画画 - js Paint
开源·画图·ms·画画
mmsx4 小时前
MapLibre 实战 11|用户说"我的地块丢了":一个 sealed class 图层模型,和四个让我重构三版的坑
android·前端·开源
追涨杀跌老能手4 小时前
GD32H759 + RT-Thread 工控实战--第4篇 SDRAM,SDIO,以及触摸屏
开源·嵌入式
DolphinScheduler社区5 小时前
Apache DolphinScheduler 3.4.3 发布!权限安全与稳定性全面增强,调度补火即将上线
开源·agent·海豚调度·大数据工作流调度
FIT2CLOUD飞致云6 小时前
GPU监控支持华为昇腾设备,防火墙管理焕新,虚拟机管理下放至专业版,1Panel v2.3.0版本发布
运维·ai·开源·1panel·运维面板