了解 Angular FormBuilder with Groups 和 ngModel 数据并且 how/if 它们可以一起使用?

Understanding Angular FormBuilder with Groups and ngModel data and how/if they can be used together?

我 运行 在我的 Angular 应用程序中尝试使用 FormBuilder 时遇到了一些问题,以及如何根据我的 [=17= 在表单中设置默认值]数据。

在我的 class 中,我有以下代码:

form: FormGroup;

constructor(
    private fb: FormBuilder,
) { }

ngOnInit() {

    this.form = this.fb.group({
        category: ['', [Validators.required]],
        quantity: [1, [Validators.required]],
        size: ['', [Validators.required]],
        title: ['', [Validators.required]],
    });
}

当我查看模板中的 {{ form.value | json }} 时,它显示了带有空值的原始值。所以我决定尝试像这样在 FormBuilder 组中设置默认值:

    this.form = this.fb.group({
        category: [this.item.category, [Validators.required]],
        quantity: [this.item.quantity, [Validators.required]],
        size: [this.item.size, [Validators.required]],
        title: [this.item.title, [Validators.required]],
    });

但是我得到了这些错误:

ERROR Error: formGroup expects a FormGroup instance. 
ERROR TypeError: Cannot read properties of undefined (reading 'category')
ERROR TypeError: Cannot read properties of undefined (reading 'value')

这是我的表单模板:

<form [formGroup]="form">
        <ion-item lines="none">
            <ion-label position="stacked">Category</ion-label>
            <ion-select [(ngModel)]="item.category" [ngModelOptions]="{standalone: true}">
                <ion-select-option *ngFor="let category of categories" [value]="category">
                    {{ category }}
                </ion-select-option>
            </ion-select>
        </ion-item>

        <ion-item lines="none">
            <ion-label position="stacked">Title</ion-label>
            <ion-input [(ngModel)]="item.title" [ngModelOptions]="{standalone: true}"></ion-input>
        </ion-item>

        <ion-item lines="none">
            <ion-label position="stacked">Size</ion-label>
            <ion-input [(ngModel)]="item.size" [ngModelOptions]="{standalone: true}"></ion-input>
        </ion-item>

        <ion-item lines="none">
            <ion-label position="stacked">Quantity</ion-label>
            <ion-input type="number" [(ngModel)]="item.quantity" [ngModelOptions]="{standalone: true}"></ion-input>
        </ion-item>

    </form>

有没有想过我的方法有什么问题以及如何从我的 this.item 中获取默认值以显示在表单中?

关于表单有 2 种方法:模板驱动(.html 中有更多逻辑和响应式(.ts 中有更多逻辑和控制)。使用 formBuilder 注入和 [formGroup]="form" 你选择了反应式方法,这种方法在经验丰富的开发人员中更为普遍,而且往往更舒适,因为它可以更好地控制你的表单。

通过这种方法使用双向数据绑定不是一个好习惯。您应该将 formControlName="controlNameXYZ" 放入相应的输入字段,并对构建表单时定义的所有输入字段执行此操作。

不要忘记在模块的 imports 数组中包含 ReactiveFormsModule(或者 AppModule,如果整个应用程序中只有一个)。

Zerospi,问题是您在变量“item”中有数据之前就创建了表单 - 这就是您看不到值的原因

  1. 切勿将响应式表单和模板驱动 (ngModel) 混合在一起

    使用 [(ngModel)]="variable" [ngModelOptions]="{standalone: true} 只是为了获取 不属于 FormGroup 的输入。

    例如,您可以有一个“复选框”来显示新的输入。有些喜欢

     movil:boolean=false;
     form=new FormGroup({
       phone:new FormControl()
       mobile:new FormControl()
     })
     <form [formGroup]="form">
       Phone<input formControlName="phone">
       <input type="checkbox" [(ngModel)]="movil" 
               [ngModelOptions]="{standalone:true}">Mobile
       <input *ngIf="movil" formControlName="mobile">
     </form>
    

    嗯,真的用

       <input type="checkbox" [ngModel]="movil" 
               (ngModelChange)="movil=$event;!$event && form.get('mobile').setValue('')
               [ngModelOptions]="{standalone:true}">Mobile
    

    如果我们取消选中“清理”FormControl“移动”

    如何控制一个FormGroup?

  2. 一般我们可以在途中有一个功能

    getFromGroup(data:any=null)
    {
       data=data || {phone:'',mobile:''}
       return this.fb.group({
          phone:[data.phone,Validators.required]
          mobile:data.mobile
       }
    }
    

    并使用

    this.form=this.getFormGroup(this.item) //if we have an object "this.item"
    this.form=this.getFormGroup() //if we want an empty Form
    
  3. 另一种方法是创建表单并使用 patchValue()

    this.form=this.fb.group({
       phone:['',Validators.required]
       mobile:''
    }
    this.form.patchValue(this.item)
    
  4. 为了避免初始错误(例如,我们在调用 API 之后创建表单),有时 util 使用类似

    <form *ngIf="form" [formGroup]="form">
    ...
    </form>
    
  5. 记住FormControl是禁用的,不要在form.value中显示,你需要使用form.getRawValue()