背景
- 在设计器中调整物料属性时,鉴于组件及其属性数量庞大,难以一一牢记每个属性的默认值,因此,为每个属性增设一个重置按钮变得至关重要。这一改进将极大地方便用户在需要时快速将属性恢复到初始状态,从而提升操作效率和用户体验。
- 物料的属性没有设置默认值,在设计器中不修改保存后schema中是没有这一项属性的。然而一旦在设计器中修改了该属性无论怎么操作也不能回到schema中没有该项属性的时候。
目的
- 简化属性配置提高开发效率(针对背景1)
- 提供一个删除schema中物料属性的方案(针对背景2)
方案
- 在ext仓库中开发一个resetsetter来支持重置当前物料属性到默认状态(defaultValue/initialValue)。
- 在物料描述中使用该setter。
- 在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
代码仓库
engine:github.com/ChiZng/lowc...
本文正在参加阿里低代码引擎征文活动