
本文介绍如何使用 angular + cdk drag & drop + reactive forms 实现:点击按钮弹出表单,输入组件名称、描述、类型,并动态添加属性(含默认值与数据类型),最终将新组件渲染到拖拽面板中。
在构建可视化低代码平台或流程编排工具时,常需支持用户动态创建可复用的 UI 组件,并将其拖入画布。Angular 提供了强大的响应式表单(Reactive Forms)与 @angular/cdk/drag-drop 模块,结合 Taiga UI(如 tuiDialog、tuiSelect)可快速搭建专业级交互界面。
✅ 核心功能实现要点
1. 弹窗表单:使用 tuiDialog 管理状态
通过 [(tuiDialog)]="open" 双向绑定控制模态框显隐,配合 tuiDialogOptions 设置标题与尺寸。表单采用 FormGroup 管理字段状态:
exampleForm = new FormGroup({
nameOfComponent: new FormControl('', [Validators.required]),
description: new FormControl(''),
});⚠️ 注意:formControlName 必须与 FormGroup 中的键名严格一致,否则无法双向绑定。
2. 动态属性管理:使用 FormArray
每个组件可拥有多个属性(如 defaultValue、type),推荐用 FormArray 统一管理:
// 在 ngOnInit() 中初始化
this.DragAndDropForm = new FormGroup({
name: this.exampleForm.get('nameOfComponent'),
description: this.exampleForm.get('description'),
componentType: new FormControl(this.chosenComponent),
attributes: new FormArray([]) // ? 关键:空数组承载属性组
});
// 添加新属性方法
addAttribute() {
const attrGroup = new FormGroup({
defaultValue: new FormControl('', Validators.required),
type: new FormControl('int', Validators.required)
});
(this.DragAndDropForm.get('attributes') as FormArray).push(attrGroup);
}对应 HTML 中使用 *ngFor 渲染:
3. 拖拽区域:CDK 集成与组件渲染
利用 cdkDropList 和 cdkDrag 实现拖拽容器与可拖拽项。关键点:新组件需以 示例(动态追加“Kraftwerk”组件): 云模块_YunMOK网站管理系统采用PHP+MYSQL为编程语言,搭载自主研发的模块化引擎驱动技术,实现可视化拖拽无技术创建并管理网站!如你所想,无限可能,支持创建任何网站:企业、商城、O2O、门户、论坛、人才等一块儿搞定!永久免费授权,包括商业用途; 默认内置三套免费模板。PC网站+手机网站+适配微信+文章管理+产品管理+SEO优化+组件扩展+NEW Login界面.....目测已经遥遥领先.. 并在模板中循环渲染: 表单提交应调用服务层发送 POST 请求。避免硬编码 URL,建议封装至 ApiService: 通过以上结构化实现,你将获得一个可扩展、易维护、符合 Angular 最佳实践的动态组件管理系统,为后续支持属性绑定、连接线逻辑、JSON Schema 导出等高级功能奠定坚实基础。
// 在 submitComponent() 中保存后执行
const newComponent = {
id: Date.now(),
name: this.exampleForm.value.nameOfComponent,
description: this.exampleForm.value.description,
type: this.chosenComponent,
icon: '⚡', // 或 SVG 字符串
attributes: this.DragAndDropForm.get('attributes').value
};
// 将 newComponent 推入对应 category 的组件列表(如 this.einspeiserComponents)
this.einspeiserComponents.push(newComponent);4. 后端对接与数据持久化
submitComponent(): void {
if (this.DragAndDropForm.invalid) return;
const payload = {
...this.exampleForm.value,
type: this.chosenComponent,
attributes: this.DragAndDropForm.get('attributes').value
};
this.apiService.postComponent(payload).subscribe({
next: res => {
console.log('✅ Component saved:', res);
this.open = false; // 关闭弹窗
this.resetForm(); // 重置表单
},
error: err => console.error('❌ Save failed:', err)
});
}
private resetForm(): void {
this.exampleForm.reset();
this.chosenComponent = this.componentTypes[0];
(this.DragAndDropForm.get('attributes') as FormArray).clear();
}? 注意事项总结









