@hzab/form-render 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,14 @@
1
+ # @hzab/form-render@1.3.1
2
+
3
+ feat: 表单 onChange 事件(目前仅做触发,值计算后续优化)
4
+
1
5
  # @hzab/form-render@1.3.0
2
6
 
3
7
  break: 去除 lib,默认 src
4
8
 
5
9
  # @hzab/form-render@1.2.5
6
- - fix: LocationListPicker组件高度调整与删除点位修复
10
+
11
+ - fix: LocationListPicker 组件高度调整与删除点位修复
7
12
 
8
13
  # @hzab/form-render@1.2.4
9
14
 
@@ -12,7 +17,7 @@ fix: UserSelect InfoRender
12
17
 
13
18
  # @hzab/form-render@1.2.3
14
19
 
15
- - fix: 富文本添加loading样式
20
+ - fix: 富文本添加 loading 样式
16
21
 
17
22
  # @hzab/form-render@1.2.2
18
23
 
package/README.md CHANGED
@@ -116,16 +116,17 @@ import FormRender from "@hzab/form-render";
116
116
 
117
117
  ### InfoPanel Attributes
118
118
 
119
- | 参数 | 类型 | 必填 | 默认值 | 说明 |
120
- | ------------- | ------- | ---- | ---------- | -------------------------------------- |
121
- | schema | Object | 是 | - | 数据信息的 schema |
122
- | schemaScope | Object | 否 | - | 全局作用域,用于实现协议表达式变量注入 |
123
- | layout | Object | 否 | horizontal | 表单布局,horizontal vertical \ inline |
124
- | initialValues | Object | 否 | - | form 初始值 |
125
- | components | Object | 否 | - | 自定义组件 |
126
- | formOptions | Object | 否 | - | createForm 的参数 |
127
- | disabled | boolean | 否 | - | 禁用状态 |
128
- | readOnly | boolean | 否 | - | 只读状态 |
119
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
120
+ | ------------- | -------- | ---- | ---------- | -------------------------------------------------- |
121
+ | schema | Object | 是 | - | 数据信息的 schema |
122
+ | schemaScope | Object | 否 | - | 全局作用域,用于实现协议表达式变量注入 |
123
+ | layout | Object | 否 | horizontal | 表单布局,horizontal vertical \ inline |
124
+ | initialValues | Object | 否 | - | form 初始值 |
125
+ | components | Object | 否 | - | 自定义组件 |
126
+ | formOptions | Object | 否 | - | createForm 的参数 |
127
+ | disabled | boolean | 否 | - | 禁用状态 |
128
+ | readOnly | boolean | 否 | - | 只读状态 |
129
+ | onChange | Function | 否 | - | 表单 onChange 事件(目前仅做触发,值计算后续优化) |
129
130
 
130
131
  ### 方法 Methods
131
132
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/form-render",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -0,0 +1,132 @@
1
+ import _ from "lodash";
2
+
3
+ /** 自增容器 */
4
+ export const arrayList = ["ArrayTable", "ArrayCards"];
5
+ /** 不需要绑定事件的目标 */
6
+ export const skipBindList = ["FormCollapse", "FormCollapse.CollapsePanel"];
7
+ /** change 回调返回 parent 数据的组件 */
8
+ export const returnParentValue = ["ArrayTable", "ArrayCards"];
9
+
10
+ /**
11
+ * schema 每项添加 onChange,解决无全局 onChange 问题
12
+ * @param schema
13
+ * @param onChange
14
+ * @returns
15
+ */
16
+ export const bindOnChange = (schema, opt) => {
17
+ const { schemaScope, onChange, formRender, parent, isCloneDeep = true } = opt || {};
18
+ let _schema = isCloneDeep ? _.cloneDeep(schema) : schema;
19
+ _schema = _schema.schema || _schema;
20
+ Object.keys(_schema.properties || {})?.forEach((key) => {
21
+ let item = _schema.properties[key];
22
+ const componentName = item["x-component"];
23
+ // 解决 name 丢失的问题
24
+ item.name = key;
25
+
26
+ if (item && !item["x-component-props"]) {
27
+ item["x-component-props"] = {};
28
+ }
29
+
30
+ const bindParams = {
31
+ componentName,
32
+ target: item["x-component-props"],
33
+ targetKey: key,
34
+ targetId: key,
35
+ formOnChange: onChange,
36
+ schemaScope,
37
+ formRender,
38
+ parent,
39
+ };
40
+
41
+ // 不需要绑定事件的目标:折叠面板不需要设置 onChange 事件,否则会导致触发多次
42
+ if (!skipBindList.includes(componentName)) {
43
+ // 绑定新的 change 事件
44
+ bindCallback({
45
+ ...bindParams,
46
+ actionName: "onChange",
47
+ });
48
+ }
49
+
50
+ // 处理自增表格、卡片等情况
51
+ if (arrayList.includes(componentName)) {
52
+ bindOnChange(item.items, {
53
+ ...opt,
54
+ parent: item,
55
+ isCloneDeep: false,
56
+ });
57
+ // 处理点击新增、删除、排序操作
58
+ const actions = ["onAdd", "onCopy", "onRemove", "onMoveDown", "onMoveUp"];
59
+ actions.forEach((actionName) => {
60
+ bindCallback({
61
+ ...bindParams,
62
+ actionName,
63
+ });
64
+ });
65
+ }
66
+
67
+ // 处理嵌套的情况
68
+ if (item.properties) {
69
+ bindOnChange(item, {
70
+ ...opt,
71
+ isCloneDeep: false,
72
+ });
73
+ }
74
+ });
75
+ return _schema;
76
+ };
77
+
78
+ /**
79
+ * 添加回调函数
80
+ * @param target
81
+ * @param name
82
+ * @param formOnChange
83
+ */
84
+ export const bindCallback = (opt) => {
85
+ const { target, actionName, schemaScope, formOnChange } = opt || {};
86
+ const tempFn = target[actionName];
87
+ target[actionName] = function (...sourceArgs) {
88
+ // 处理结果数据,各组件返回数据格式不一致
89
+ const res = handleChangeValue({
90
+ ...opt,
91
+ sourceArgs,
92
+ });
93
+ // 触发组件 onChange 事件
94
+ if (typeof tempFn === "string" && tempFn.startsWith("{{") && tempFn.endsWith("}}")) {
95
+ // schemaScope 传入方式
96
+ const fn = schemaScope && schemaScope[tempFn.replace(/^\{\{/, "").replace(/\}\}$/, "")];
97
+ typeof fn === "function" && fn(...sourceArgs, res);
98
+ } else if (typeof tempFn === "function") {
99
+ // 直接传入函数的方式
100
+ tempFn(...sourceArgs, res);
101
+ }
102
+ formOnChange && formOnChange(res);
103
+ };
104
+ };
105
+
106
+ /**
107
+ * 从 onChange 事件中获取数据
108
+ * @param args
109
+ */
110
+ export const handleChangeValue = (opt) => {
111
+ const { componentName, formRender, parent, targetKey, actionName, sourceArgs } = opt || {};
112
+ console.log("parent", parent);
113
+ // 自增表格、卡片无法获知当前编辑内容所在的索引,导致无法知道当前值
114
+ const res = {
115
+ key: targetKey,
116
+ actionName: actionName,
117
+ formRender,
118
+ formValues: formRender.values,
119
+ sourceArgs: sourceArgs,
120
+ // value: formRender.getValuesIn(targetKey),
121
+ // parent,
122
+ // TODO: 自增情况下无法获知索引
123
+ // parentValue: formRender.getValuesIn(parent?.name),
124
+ };
125
+
126
+ // TODO: 自增返回父级值?
127
+ // if (returnParentValue.includes(parent?.["x-component"])) {
128
+ // res.value = res.parentValue;
129
+ // }
130
+
131
+ return res;
132
+ };
package/src/index.tsx CHANGED
@@ -30,9 +30,11 @@ import {
30
30
  ArrayCards,
31
31
  } from "c-formily-antd";
32
32
  import { Card, Slider, Rate } from "antd";
33
+
33
34
  // 自定义组件
34
35
  import * as customComponents from "./components/index";
35
36
  import { GlobalPropsContext } from "./common/global-props-context";
37
+ import { bindOnChange } from "./common/schema-handler";
36
38
 
37
39
  import "./index.less";
38
40
 
@@ -146,6 +148,14 @@ const FormRender = forwardRef((props: any, parentRef) => {
146
148
  ...props.schema?.form,
147
149
  };
148
150
 
151
+ const schema = useMemo(() => {
152
+ return bindOnChange(props.schema, {
153
+ schemaScope: props.schemaScope,
154
+ onChange: props.onChange,
155
+ formRender,
156
+ });
157
+ }, []);
158
+
149
159
  return (
150
160
  <GlobalPropsContext.Provider value={props}>
151
161
  <Form
@@ -158,7 +168,7 @@ const FormRender = forwardRef((props: any, parentRef) => {
158
168
  onAutoSubmitFailed={autoSubmitFailed}
159
169
  >
160
170
  <FormLayout {...formLayoutProps}>
161
- <SchemaField schema={props.schema.schema}></SchemaField>
171
+ <SchemaField schema={schema}></SchemaField>
162
172
  <div className="form-render-footer xxm">{footer}</div>
163
173
  </FormLayout>
164
174
  </Form>