Angular中从服务获取用户数据动态赋值FormGroup及报错解决
问题根源
你的报错来自两个核心问题:
- 执行时序错乱:构造函数中调用的接口是异步请求,
ngOnInit初始化表单时,接口响应还没返回,此时this.me为undefined,直接读取this.me.lastname等属性本身就会触发空值错误。 - 表单初始状态异常:你一开始将
signupForm初始化为空的FormGroup,模板首次渲染时找不到lastname/firstname/email这些控件,直接抛出找不到控件的错误。另外你报错信息里的firsname是拼写失误,检查模板里是否有手误拼错控件名的情况。
修复方案
不要在初始化表单时直接绑定尚未获取到的接口数据,遵循「先初始化完整表单结构 -> 再请求接口 -> 最后用patchValue赋值」的流程即可:
- 移除类属性上初始化的空
FormGroup,在ngOnInit中优先构建带空默认值的完整表单,保证模板渲染时所有控件都已存在。 - 表单初始化完成后再调用用户信息接口。
- 接口返回数据后,调用响应式表单的
patchValue方法批量给控件赋值,不要在构建表单时直接引用未赋值的this.me属性。
修复后的完整TS代码如下:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; // 保留你原有的MeService、Me类型等导入 @Component({ selector: 'app-user-profile', // 替换为你自己的组件选择器 templateUrl: './form.html' }) export class UserProfileComponent implements OnInit { me!: Me; signupForm!: FormGroup; constructor( private meService: MeService, private fb: FormBuilder ) {} ngOnInit(): void { // 先初始化完整表单,所有控件先用空字符串作为默认值 this.signupForm = this.fb.group({ lastname: [ '', [ Validators.required, Validators.maxLength(30), Validators.minLength(2), Validators.pattern("^[a-zA-Z éèàâëê'-]+$"), ] ], firstname: [ '', [ Validators.required, Validators.maxLength(30), Validators.minLength(2), Validators.pattern("^[a-zA-Z éèàâëê'-]+$"), ] ], email: [ '', [ Validators.required, Validators.email, ], ], }); // 表单结构就绪后再请求用户数据 this.CurrentUser(); } CurrentUser(){ this.meService.me().subscribe( result => { this.me = result; // 接口返回后给表单批量赋值 this.signupForm.patchValue({ lastname: this.me.lastname, firstname: this.me.firstname, email: this.me.email }); } ) } // 控件getter保持原有逻辑即可 get lastname(): FormControl { return this.signupForm.get('lastname') as FormControl; } get firstname(): FormControl { return this.signupForm.get('firstname') as FormControl; } get email(): FormControl { return this.signupForm.get('email') as FormControl; } // 补充表单提交方法 onSubmit() { if (this.signupForm.invalid) return; // 调用保存接口,传this.signupForm.value即可 } }
可选优化
如果不想让用户看到输入框先显示空值、再填充用户数据的闪烁效果,可以在表单标签上加判断,等用户数据加载完成后再渲染表单,同时记得给submit按钮绑定提交事件:
<form [formGroup]="signupForm" *ngIf="me" (ngSubmit)="onSubmit()"> <div class="container"> <!-- 你原有的表单项内容无需修改 --> <div class="form-group mb-5"> <label for="exampleInputEmail1">Nom :</label> <div class="d-flex align-items-center"> <input type="text" class="form-control" formControlName="lastname"> <i class="fa-solid fa-lock pl-3"></i> </div> </div> <div class="form-group mb-5"> <label for="exampleInputEmail1">Prenom :</label> <div class="d-flex align-items-center"> <input type="text" class="form-control" formControlName="firstname"> <i class="fa-solid fa-lock pl-3"></i> </div> </div> <div class="form-group mb-5"> <label for="exampleInputEmail1">Email :</label> <div class="d-flex align-items-center"> <input type="email" class="form-control" formControlName="email" id="exampleInputEmail1" aria-describedby="emailHelp"> <i class="fa-solid fa-lock pl-3"></i> </div> </div> <button type="submit" class="btn btn-primary">Sauvegarder</button> </div> </form>
内容的提问来源于stack exchange,提问作者Wvxil
相关产品推荐
相关产品推荐

