Skip to content

Commit 26112d7

Browse files
committed
feat(Form): support skyline render
1 parent 57818b6 commit 26112d7

2 files changed

Lines changed: 70 additions & 72 deletions

File tree

packages/components/form-item/form-item.ts

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export default class FormItem extends SuperComponent {
4545
formRules: [],
4646
innerLabelAlign: '',
4747
innerLabelWidth: '',
48-
form: {},
4948
colon: false,
5049
innerShowErrorMessage: true,
5150
innerContentAlign: '',
@@ -67,51 +66,51 @@ export default class FormItem extends SuperComponent {
6766
relations: RelationsOptions = {
6867
'../form/form': {
6968
type: 'parent',
70-
linked(target) {
71-
target.registerChild(this);
72-
this.form = target;
73-
const { globalConfig } = this.data;
74-
const { requiredMark, labelAlign, labelWidth, showErrorMessage } = this.properties;
75-
const formRules = target.data.rules?.[this.properties.name];
76-
const isRequired = formRules?.some((rule) => rule.required);
77-
78-
const { contentAlign } = this.properties;
79-
const innerContentAlign = contentAlign || target.data.contentAlign || '';
80-
81-
this.setData({
82-
formRules: formRules || [],
83-
colon: target.data.colon,
84-
innerLabelAlign: labelAlign || target.data.labelAlign,
85-
innerLabelWidth: normalizeLabelWidth(labelWidth || target.data.labelWidth),
86-
innerContentAlign,
87-
contentStyle: innerContentAlign ? `text-align: ${innerContentAlign}` : '',
88-
innerRequiredMark: requiredMark ?? target.data.requiredMark ?? globalConfig.requiredMark ?? isRequired,
89-
innerShowErrorMessage:
90-
typeof showErrorMessage === 'boolean' ? showErrorMessage : target.properties.showErrorMessage,
91-
requiredMarkPosition: target.data.requiredMarkPosition || globalConfig.requiredMarkPosition || 'left',
92-
});
93-
},
94-
unlinked() {
95-
if (this.form) {
96-
this.form.unregisterChild(this.properties.name);
97-
}
69+
// 关联建立时主动向父组件同步一次配置
70+
linked() {
71+
this.syncFromParent();
9872
},
9973
},
10074
};
10175

10276
lifetimes = {
10377
ready() {
104-
this.initFormItem();
105-
},
106-
/* istanbul ignore next */
107-
detached() {
108-
if (this.form) {
109-
this.form.unregisterChild(this.properties.name);
110-
}
78+
// Skyline/glass-easel 下 relations.linked 可能未触发,ready 时再主动同步一次兜底
79+
this.syncFromParent();
11180
},
11281
};
11382

11483
methods = {
84+
// 从父组件 t-form 同步配置(父 -> 子),集中处理「form-item 自身属性优先级高于 Form」的逻辑。
85+
// 父组件引用统一通过 relations 注入的 $parent(基于 getRelationNodes)获取,兼容 Skyline 下 linked 仅触发一次的问题
86+
syncFromParent() {
87+
const parent = this.$parent;
88+
if (!parent) return;
89+
90+
const { globalConfig } = this.data;
91+
const { requiredMark, labelAlign, labelWidth, showErrorMessage, contentAlign, name } = this.properties;
92+
const parentData = parent.data;
93+
94+
const formRules = parentData.rules?.[name];
95+
const isRequired = formRules?.some((rule) => rule.required);
96+
const innerContentAlign = contentAlign || parentData.contentAlign || '';
97+
98+
this.setData({
99+
formRules: formRules || [],
100+
colon: parentData.colon,
101+
innerLabelAlign: labelAlign || parentData.labelAlign,
102+
innerLabelWidth: normalizeLabelWidth(labelWidth || parentData.labelWidth),
103+
innerContentAlign,
104+
contentStyle: innerContentAlign ? `text-align: ${innerContentAlign}` : '',
105+
innerRequiredMark: requiredMark ?? parentData.requiredMark ?? globalConfig.requiredMark ?? isRequired,
106+
innerShowErrorMessage: typeof showErrorMessage === 'boolean' ? showErrorMessage : parentData.showErrorMessage,
107+
requiredMarkPosition: parentData.requiredMarkPosition || globalConfig.requiredMarkPosition || 'left',
108+
});
109+
110+
// 父组件可能在子组件之后才完成数据准备,这里主动同步初始值,避免 Skyline 下初始值丢失
111+
this.setInitialValue();
112+
},
113+
115114
calcErrorClasses(errorList = this.data.errorList) {
116115
if (!this.data.innerShowErrorMessage) return '';
117116
if (!errorList || errorList.length === 0) return '';
@@ -135,33 +134,31 @@ export default class FormItem extends SuperComponent {
135134
});
136135
},
137136

138-
// 初始化表单项
139-
initFormItem() {
140-
this.setInitialValue();
141-
},
142-
143137
// 设置初始值
144138
setInitialValue() {
145139
const { name } = this.properties;
146-
if (name && this.form) {
147-
const data = this.form.properties.data || {};
140+
const parent = this.$parent;
141+
if (name && parent) {
142+
const data = parent.properties.data || {};
148143
this.initialValue = data[name];
149144
}
150145
},
151146

152147
// 获取表单数据
153148
getFormData() {
154-
if (this.form) {
155-
return this.form.properties.data || {};
149+
const parent = this.$parent;
150+
if (parent) {
151+
return parent.properties.data || {};
156152
}
157153
return {};
158154
},
159155

160156
// 获取当前值
161157
getValue() {
162158
const { name } = this.properties;
163-
if (name && this.form) {
164-
const data = this.form.properties.data || {};
159+
const parent = this.$parent;
160+
if (name && parent) {
161+
const data = parent.properties.data || {};
165162
return data[name];
166163
}
167164
return undefined;
@@ -218,7 +215,7 @@ export default class FormItem extends SuperComponent {
218215
// 分析验证结果
219216
analysisValidateResult(results) {
220217
const { globalConfig } = this.data;
221-
const errorMessage = (this.form && this.form.properties.errorMessage) || globalConfig.errorMessage;
218+
const errorMessage = this.$parent?.properties.errorMessage || globalConfig.errorMessage;
222219
const labelName = this.properties.label || this.properties.name;
223220

224221
const errorList = results

packages/components/form/form.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ export default class Form extends SuperComponent {
2626
relations: RelationsOptions = {
2727
'../form-item/form-item': {
2828
type: 'child',
29-
linked() {},
29+
// 子组件挂载时主动下发一次表单配置,兼容 Skyline 下 linked 仅触发一次的情况
30+
linked(target) {
31+
target.syncFromParent?.();
32+
},
3033
},
3134
};
3235

3336
data = {
3437
prefix,
3538
classPrefix: name,
36-
children: [],
3739
initialData: {},
3840
fields: [],
3941
};
4042

43+
observers = {
44+
// 父组件配置变化时,统一下发到所有 form-item,保证 父 -> 子 的属性同步
45+
'labelAlign, labelWidth, colon, contentAlign, requiredMark, requiredMarkPosition, showErrorMessage, rules'() {
46+
this.getChildren().forEach((child: any) => child.syncFromParent?.());
47+
},
48+
};
49+
4150
lifetimes = {
4251
ready() {
4352
this.initFormData();
@@ -58,28 +67,19 @@ export default class Form extends SuperComponent {
5867
});
5968
},
6069

61-
// 注册子组件
62-
registerChild(child) {
63-
const { children } = this.data;
64-
if (!children.find((item) => item.data.name === child.data.name)) {
65-
children.push(child);
66-
this.setData({ children });
67-
}
68-
},
69-
70-
// 注销子组件
71-
unregisterChild(childName) {
72-
const { children } = this.data;
73-
const index = children.findIndex((item) => item.data.name === childName);
74-
if (index > -1) {
75-
children.splice(index, 1);
76-
this.setData({ children });
70+
// 获取所有 form-item 子组件
71+
// 优先使用 relations 注入的 $children(基于 getRelationNodes,兼容 Skyline),兜底使用节点查询
72+
getChildren() {
73+
let items = this.$children;
74+
if (!items?.length) {
75+
items = this.selectAllComponents(`.${prefix}-form-item`);
7776
}
77+
return items || [];
7878
},
7979

8080
// 验证表单
8181
async validate() {
82-
const { children } = this.data;
82+
const children = this.getChildren();
8383
const { data } = this.properties;
8484
const validatePromises = children.map((child) => child.validate(data, 'all', this.properties.showErrorMessage));
8585

@@ -110,7 +110,7 @@ export default class Form extends SuperComponent {
110110
const firstErrorKey = Object.keys(validateResult)[0];
111111
if (!firstErrorKey) return;
112112

113-
const { children } = this.data;
113+
const children = this.getChildren();
114114
const errorChild = children.find((child) => child.properties.name === firstErrorKey);
115115
if (!errorChild) return;
116116

@@ -120,7 +120,7 @@ export default class Form extends SuperComponent {
120120
// 纯净验证(不显示错误信息)
121121
async validateOnly(params) {
122122
const { fields, trigger = 'all' } = params;
123-
const { children } = this.data;
123+
const children = this.getChildren();
124124

125125
const validatePromises = children
126126
.filter((child) => {
@@ -220,7 +220,8 @@ export default class Form extends SuperComponent {
220220

221221
// 重置表单
222222
reset() {
223-
const { children, initialData, fields } = this.data;
223+
const children = this.getChildren();
224+
const { initialData, fields } = this.data;
224225
const resetData = {};
225226

226227
children.forEach((child) => {
@@ -241,7 +242,7 @@ export default class Form extends SuperComponent {
241242

242243
// 清空验证结果
243244
clearValidate(fields) {
244-
const { children } = this.data;
245+
const children = this.getChildren();
245246

246247
children.forEach((child) => {
247248
if (!fields || fields.includes(child.data.name)) {
@@ -252,7 +253,7 @@ export default class Form extends SuperComponent {
252253

253254
// 设置验证信息
254255
setValidateMessage(validateMessage) {
255-
const { children } = this.data;
256+
const children = this.getChildren();
256257

257258
children.forEach((child) => {
258259
if (validateMessage[child.data.name]) {

0 commit comments

Comments
 (0)