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处理逻辑实现

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()}</>)
      }
  }

重置值处理

  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:https://github.com/ChiZng/lowcode-engine-ext/tree/feat/resetsetter

engine:https://github.com/ChiZng/lowcode-engine/tree/feat/reset-attribute

### LowCode Engine 使用指南 LowCode Engine 是阿里巴巴钉钉团队开源的一款低代码开发工具,其设计初衷是为开发者提供构建低代码平台的基础设施。它基于 React 技术栈实现,强调最小内核、插件化拓展和高度定制化,适合开发者基于其核心能力进行二次开发[^2]。 #### 1. 核心功能与技术架构 LowCode Engine 的核心特性包括: - **最小内核**:引擎设计轻量化,核心模块仅包含最基础的运行时能力。 - **插件化扩展**:通过插件机制实现功能的灵活扩展,开发者可以根据需求开发或集成插件。 - **物料体系**:支持组件、模板、设置器等物料的管理与扩展,便于构建丰富的可视化开发资源库[^3]。 - **开放 API**:提供丰富的 API 接口,支持开发者进行深度定制和集成。 #### 2. 开发环境准备 在使用 LowCode Engine 之前,需确保系统环境满足以下要求: - Node.js 版本 >= 14.x - npm 或 yarn 包管理工具 - 熟悉 React 开发框架 - 基本的前端工程化知识(如 Webpack、Babel 等) 建议使用官方推荐的脚手架工具 `lowcode-init` 快速初始化项目环境,具体命令如下: ```bash npm install -g lowcode-init lowcode-init new my-lowcode-project cd my-lowcode-project npm start ``` #### 3. 核心开发方向 LowCode Engine 的二次开发主要包括以下几个方向: - **组件开发**:支持自定义业务组件的注册与使用,提升平台的可复用性。 - **插件开发**:通过插件机制扩展编辑器功能,如新增工具面板、快捷操作等。 - **设置器定制**:为组件属性提供可视化配置界面,提升编辑器易用性。 - **架构扩展**:根据业务需求调整引擎的运行时架构,如集成状态管理、路由系统等。 #### 4. 点击事件的配置 在 LowCode Engine 中,点击事件的配置通常通过以下方式实现- 在编辑器中选择目标组件。 - 在属性面板中找到“事件”部分。 - 选择“点击事件”并绑定相应的回调函数或页面跳转逻辑。 例如,可以通过以下方式在代码中定义点击事件: ```javascript const onClick = (event) => { console.log('按钮被点击', event); }; <Button onClick={onClick}>点击我</Button> ``` 此外,LowCode Engine 提供了可视化配置界面,允许开发者通过拖拽方式快速绑定事件逻辑,从而降低开发门槛并提升效率[^5]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值