Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 45 additions & 48 deletions packages/components/form-item/form-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export default class FormItem extends SuperComponent {
formRules: [],
innerLabelAlign: '',
innerLabelWidth: '',
form: {},
colon: false,
innerShowErrorMessage: true,
innerContentAlign: '',
Expand All @@ -67,51 +66,51 @@ export default class FormItem extends SuperComponent {
relations: RelationsOptions = {
'../form/form': {
type: 'parent',
linked(target) {
target.registerChild(this);
this.form = target;
const { globalConfig } = this.data;
const { requiredMark, labelAlign, labelWidth, showErrorMessage } = this.properties;
const formRules = target.data.rules?.[this.properties.name];
const isRequired = formRules?.some((rule) => rule.required);

const { contentAlign } = this.properties;
const innerContentAlign = contentAlign || target.data.contentAlign || '';

this.setData({
formRules: formRules || [],
colon: target.data.colon,
innerLabelAlign: labelAlign || target.data.labelAlign,
innerLabelWidth: normalizeLabelWidth(labelWidth || target.data.labelWidth),
innerContentAlign,
contentStyle: innerContentAlign ? `text-align: ${innerContentAlign}` : '',
innerRequiredMark: requiredMark ?? target.data.requiredMark ?? globalConfig.requiredMark ?? isRequired,
innerShowErrorMessage:
typeof showErrorMessage === 'boolean' ? showErrorMessage : target.properties.showErrorMessage,
requiredMarkPosition: target.data.requiredMarkPosition || globalConfig.requiredMarkPosition || 'left',
});
},
unlinked() {
if (this.form) {
this.form.unregisterChild(this.properties.name);
}
// 关联建立时主动向父组件同步一次配置
linked() {
this.syncFromParent();
},
},
};

lifetimes = {
ready() {
this.initFormItem();
},
/* istanbul ignore next */
detached() {
if (this.form) {
this.form.unregisterChild(this.properties.name);
}
// Skyline/glass-easel 下 relations.linked 可能未触发,ready 时再主动同步一次兜底
this.syncFromParent();
},
};

methods = {
// 从父组件 t-form 同步配置(父 -> 子),集中处理「form-item 自身属性优先级高于 Form」的逻辑。
// 父组件引用统一通过 relations 注入的 $parent(基于 getRelationNodes)获取,兼容 Skyline 下 linked 仅触发一次的问题
syncFromParent() {
const parent = this.$parent;
if (!parent) return;

const { globalConfig } = this.data;
const { requiredMark, labelAlign, labelWidth, showErrorMessage, contentAlign, name } = this.properties;
const parentData = parent.data;

const formRules = parentData.rules?.[name];
const isRequired = formRules?.some((rule) => rule.required);
const innerContentAlign = contentAlign || parentData.contentAlign || '';

this.setData({
formRules: formRules || [],
colon: parentData.colon,
innerLabelAlign: labelAlign || parentData.labelAlign,
innerLabelWidth: normalizeLabelWidth(labelWidth || parentData.labelWidth),
innerContentAlign,
contentStyle: innerContentAlign ? `text-align: ${innerContentAlign}` : '',
innerRequiredMark: requiredMark ?? parentData.requiredMark ?? globalConfig.requiredMark ?? isRequired,
innerShowErrorMessage: typeof showErrorMessage === 'boolean' ? showErrorMessage : parentData.showErrorMessage,
requiredMarkPosition: parentData.requiredMarkPosition || globalConfig.requiredMarkPosition || 'left',
});

// 父组件可能在子组件之后才完成数据准备,这里主动同步初始值,避免 Skyline 下初始值丢失
this.setInitialValue();
},

calcErrorClasses(errorList = this.data.errorList) {
if (!this.data.innerShowErrorMessage) return '';
if (!errorList || errorList.length === 0) return '';
Expand All @@ -135,33 +134,31 @@ export default class FormItem extends SuperComponent {
});
},

// 初始化表单项
initFormItem() {
this.setInitialValue();
},

// 设置初始值
setInitialValue() {
const { name } = this.properties;
if (name && this.form) {
const data = this.form.properties.data || {};
const parent = this.$parent;
if (name && parent) {
const data = parent.properties.data || {};
this.initialValue = data[name];
}
},

// 获取表单数据
getFormData() {
if (this.form) {
return this.form.properties.data || {};
const parent = this.$parent;
if (parent) {
return parent.properties.data || {};
}
return {};
},

// 获取当前值
getValue() {
const { name } = this.properties;
if (name && this.form) {
const data = this.form.properties.data || {};
const parent = this.$parent;
if (name && parent) {
const data = parent.properties.data || {};
return data[name];
}
return undefined;
Expand Down Expand Up @@ -218,7 +215,7 @@ export default class FormItem extends SuperComponent {
// 分析验证结果
analysisValidateResult(results) {
const { globalConfig } = this.data;
const errorMessage = (this.form && this.form.properties.errorMessage) || globalConfig.errorMessage;
const errorMessage = this.$parent?.properties.errorMessage || globalConfig.errorMessage;
const labelName = this.properties.label || this.properties.name;

const errorList = results
Expand Down
49 changes: 25 additions & 24 deletions packages/components/form/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,27 @@ export default class Form extends SuperComponent {
relations: RelationsOptions = {
'../form-item/form-item': {
type: 'child',
linked() {},
// 子组件挂载时主动下发一次表单配置,兼容 Skyline 下 linked 仅触发一次的情况
linked(target) {
target.syncFromParent?.();
},
},
};

data = {
prefix,
classPrefix: name,
children: [],
initialData: {},
fields: [],
};

observers = {
// 父组件配置变化时,统一下发到所有 form-item,保证 父 -> 子 的属性同步
'labelAlign, labelWidth, colon, contentAlign, requiredMark, requiredMarkPosition, showErrorMessage, rules'() {
this.getChildren().forEach((child: any) => child.syncFromParent?.());
},
};

lifetimes = {
ready() {
this.initFormData();
Expand All @@ -58,28 +67,19 @@ export default class Form extends SuperComponent {
});
},

// 注册子组件
registerChild(child) {
const { children } = this.data;
if (!children.find((item) => item.data.name === child.data.name)) {
children.push(child);
this.setData({ children });
}
},

// 注销子组件
unregisterChild(childName) {
const { children } = this.data;
const index = children.findIndex((item) => item.data.name === childName);
if (index > -1) {
children.splice(index, 1);
this.setData({ children });
// 获取所有 form-item 子组件
// 优先使用 relations 注入的 $children(基于 getRelationNodes,兼容 Skyline),兜底使用节点查询
getChildren() {
let items = this.$children;
if (!items?.length) {
items = this.selectAllComponents(`.${prefix}-form-item`);
}
return items || [];
},

// 验证表单
async validate() {
const { children } = this.data;
const children = this.getChildren();
const { data } = this.properties;
const validatePromises = children.map((child) => child.validate(data, 'all', this.properties.showErrorMessage));

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

const { children } = this.data;
const children = this.getChildren();
const errorChild = children.find((child) => child.properties.name === firstErrorKey);
if (!errorChild) return;

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

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

// 重置表单
reset() {
const { children, initialData, fields } = this.data;
const children = this.getChildren();
const { initialData, fields } = this.data;
const resetData = {};

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

// 清空验证结果
clearValidate(fields) {
const { children } = this.data;
const children = this.getChildren();

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

// 设置验证信息
setValidateMessage(validateMessage) {
const { children } = this.data;
const children = this.getChildren();

children.forEach((child) => {
if (validateMessage[child.data.name]) {
Expand Down
Loading