
angular 区不太活跃 故移动此区
因不可抗力原因要求使用 angular20 开始学这个,然后有个问题很困扰 ,就是一般每个表单都会有个对应的 model 页面上会用 formControlName 。 然后我们的 model 字段很多 在 component 里就有很多这种代码
const tubeData: TubeModel = { commonParams: this.commonParams, tubeInitDate: formatDate(formValue.tubeInitDate, 'yyyy/MM/dd HH:mm'), tubeInsertionDate: formatDate(formValue.tubeInsertionDate, 'yyyy/MM/dd HH:mm'), anticipatedTubeRemovalDate: formatDate(formValue.anticipatedTubeRemovalDate, 'yyyy/MM/dd'), tubeId: formValue.tubeId, tubeName: formValue.tubeName, tubeGroup: formValue.tubeGroup, tubeType: formValue.tubeType, tubeMaterial: formValue.tubeMaterial, tubeProductNumber: formValue.tubeProductNumber, tubeProductNumberOtherValue: formValue.tubeProductNumber || '', innerLength: formValue.innerLength, innerUnit: 'cm', bodyPosition: formValue.bodyPosition, bodyPart: formValue.bodyPart, tubeLength: formValue.tubeLength, tubeUnit: 'cm', seqNumber: formValue.seqNumber === '其他' ? formValue.seqNumberOther : formValue.seqNumber, drainage: formValue.drainage || 0, traits: { color: formValue.color, colorOther: formValue.colorOther || '', nature: formValue.nature, natureOther: formValue.natureOther || '', flavor: formValue.flavor, flavorOther: formValue.flavorOther || '', }, }; 以及这种 this.form.patchValue({ tubeGroup: tube.tubeGroup, tubeId: tube.tubeId, tubeInitDate: tube.tubeInitDate ? new Date(tube.tubeInitDate) : null, tubeInsertionDate: tube.tubeInsertionDate ? new Date(tube.tubeInsertionDate) : null, anticipatedTubeRemovalDate: tube.anticipatedTubeRemovalDate ? new Date(tube.anticipatedTubeRemovalDate) : null, tubeName: tube.tubeName, tubeType: tube.tubeType, tubeMaterial: tube.tubeMaterial, tubeProductNumber: tube.tubeProductNumber, innerLength: tube.innerLength, bodyPosition: tube.bodyPosition, bodyPart: tube.bodyPart, tubeLength: tube.tubeLength, seqNumber: tube.seqNumber, drainage: tube.drainage, }); 还有 init 的时候这种 ngOnInit(): void { this.form = this.fb.group({ tubeGroup: [null], tubeId: [null], tubeInitDate: [null], tubeInsertionDate: [null], anticipatedTubeRemovalDate: [null], tubeName: [null], tubeType: [''], tubeMaterial: [null], tubeProductNumber: [null], innerLength: [null], bodyPosition: [null], bodyPart: [''], tubeLength: [null], seqNumber: [null], seqNumberOther: [''], drainage: [null], color: [null], colorOther: [''], flavor: [null], flavorOther: [''], nature: [null], natureOther: [''], }); } 我觉得看着很冗余 字段多了一刷一大片 既然有了 model ,有办法简化这部分吗
1 c3de3f21 5 小时 1 分钟前 signal 和 effect 可以吗,都是比较新的 API? model = signal<User>({ name: '', age: 0 }); form = new FormGroup({ name: new FormControl(''), age: new FormControl(0), }); effect(() => { this.form.patchValue(this.model()); }); effect(() => { this.model.update(m => ({ ...m, ...this.form.value })); }); |
2 helee9199 OP @c3de3f21 你举的例子只有两个属性。但是我想问的是 如果我有 50 个属性,怎么优雅的处理。 就是想优化 form = new FormGroup({ name: new FormControl(''), age: new FormControl(0), });这部分 ,感觉很嗦, 有没有办法实现,因为我是 java ,有没有办法 通过 model 的 class 自动处理这部分? |
3 shakaraka PRO 1 、21 新增了 signal form ,可以尝试。 2 、标准的写法是:先在 class 里定义好 FormGroup 以及默认值,然后在 init 里或者 http reponse 后进行 patchValue 我不太懂你的 model 是什么,ng 里没这个概念。首先你得知道 form 的数据结构和后台给你的数据结构是两回事,需要赋值是标准操作 |
6 c3de3f21 4 小时 41 分钟前 ReactiveForm 或者 FormModule ,与 NgModel 选一种,后者更像是你说的那种,可是没有验证 |
9 helee9199 OP @shakaraka 就是例如我后台要存资料 这笔资料有 50 个属性 ,前端我也会写一个 50 个属性的 interface 或者 class 也就是我所说的 model 。 然后保存数据的时候封装成这个 model 传给后台 目前页面上会写 formCOntrolName='beanName' 然后这种做法就会出现我主楼里那种罗嗦的写法。 |
11 shakaraka PRO @helee9199 #9 首先你写 java 肯定知道 DTO 、VO 这些鬼东西。 先抛开 ng 的 FormGroup ,换个角度想,后端给你定义的数据类型,只是交换数据而已,彼此沟通所需要的内容而已。 但是你页面上,还有控制你页面的属性、字段等,这些后端是不需要的,所以在页面上是会有自己的一套数据结构。 你不能想当然把交换数据的结构当做是你页面上要用到的结构。 一个一个转换、赋值是最稳妥、最一目了然的做法。 |
12 helee9199 OP @shakaraka 啊 一个一个写转换赋值那这也太蠢了吧,init 的时候要做一遍 数据提交的时候又要做一遍, 真的没有什么方法或者组件能实现 页面上的 beanname 和 model 对应上了就能自动封装的操作吗? 也就是 springmvc 那种模式。form 里的 name 和 model 的 beanname 对应上 自动封装数据。 |
13 shakaraka PRO @helee9199 #12 并不会。而且现在 21 版本有了 signal form ,总体来说会好用很多。 你可以看看这个视频,不管用不用 signal form ,还是 vue 那种,我上面说的逻辑还是不变的。 你始终需要先定义,再使用,这个是个最佳实践方式。特别像是在 vue2 的时候,你动态给 data 赋值,新手还出现很多赋值了,页面没反应,又或者是表单找不到 data 里的数据了,等等。 https://www.bilibili.com/video/BV1Nys4zvEmr |