本文详解如何在 Angular 中实现“点击新增组件 → 填写名称/描述/类型 → 动态添加属性(默认值+数据类型)→ 提交后自动显示为可拖拽项”的完整流程,涵盖表单响应式设计、CDK 拖拽集成与动态表单控制。
在构建可视化配置平台(如能源系统建模、低代码设计器)时,常需支持用户动态创建带元数据的可拖拽组件。本教程以 Angular 17+(含 CDK Drag & Drop 和 Taiga UI)为基础,手把手实现从表单录入到 DOM 渲染的闭环逻辑。
// 初始化主表单(含基础字段)
exampleForm = new FormGroup({
nameOfComponent: new FormControl('', [Validators.required]),
description: new FormControl(''),
});
// 动态属性区暂用简单布尔控制(生产环境推荐 FormArray)
IsHidden = true;
addNewAttributeButtonClick() {
this.IsHidden = !this.IsHidden;
}
// ✅ 进阶方案:使用 FormArray 管理多个属性
attributes = new FormArray([
new FormGroup({
defaultValue: new FormControl('', Validators.required),
type: new FormControl('int', Validators.required),
})
]);
get attributesControls() {
return this.attributes.controls as FormGroup[];
}
addAttribute() {
this.attributes.push(
new FormGroup({
defaultValue: new FormControl('', Validators.required),
type: new FormControl('int', Validators.required),
})
);
}
提交成功后,需将新组件动态插入对应类型的 tui-accordion-item 内部,而非硬编码。推荐方案:
// 在 submitComponent() 中
submitComponent() {
const formData = this.exampleForm.value;
const attributes = this.attributes.value; // 获取所有属性
const newComponent = {
id: Date.now(), // 唯一标识
name: formData.nameOfComponent,
description: formData.description,
type: this.chosenComponent,
attributes,
icon: this.getIconByType(this.chosenComponent) // 根据类型返回 SVG 字符串
};
// ✅ 关键:将新组件推入对应类型的数据源(如 this.einspeiserComponents)
this.addComponentToSection(newComponent);
this.open = false; // 关闭弹窗
}
private addComponentToSection(comp: any) {
switch(comp.type) {
case 'Einspeiser':
this.einspeiserComponents.push(comp);
break;
case 'Versorgung':
this.versorgungComponents.push(comp);
break;
// ... 其他类型
}
}并在模板中用 *ngFor 渲染:
Einspeiser {{ comp.name }} {{ comp.description }}
本方案以「表单驱动 + 状态管理 + 动态渲染」为核心,将用户输入实时转化为可交互的拖拽元素。通过合理划分数据模型(组件类型、属性集合、UI 渲染映射),既保证了扩展性(新增类型只需修改 componentTypes 和 switch 分支),又维持了代码清晰度。后续可进一步集成撤销重做、属性校验规则配置等高级能力。