如何在 angular 中创建表单数组?
How can I create an array of forms in angular?
我想为分数中数组的每个元素创建并绑定一个 formControl
我尝试这样做,但出现控制台错误:
找不到路径为:'crime_types -> 0
的控件
找不到带有路径的控件:'crime_types -> 1 -> score'
public resultsForm: FormGroup;
constructor(
private _formBuilder: FormBuilder,
) {
this.resultsForm = this._formBuilder.group({
crime_types: this._formBuilder.array([])
});
for (let i = 0; i < this.tasks.length; i++) {
this.formArrayCrimeType.push(
this._formBuilder.group({
psychological_tasks_id: new FormControl(this.tasks[i].id),
patients_id: new FormControl(this.patientId),
score: new FormControl('', [Validators.required]),
})
);
}
}
public get formArrayCrimeType(): FormArray {
return this.resultsForm.get("crime_types") as FormArray;
}
public getNumber(): number {
this.numb = this.numb + 1;
return this.numb;
}
模板
<ng-container formArrayName="crime_types">
<ng-container *ngFor="let task of tasks" [formGroupName]="getNumber()">
<div *ngIf="task.psychological_processes_id == process.id" class="col-12 col-md-6">
<div class="form-div">
<label for="gender" class="form-tag">{{task.description}} *</label>
<select formControlName="score" class="custom-select" required>
<option selected disabled value="">Seleccionar puntaje...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">2</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
当我们有一个 FormGroups 的 FormArray 时,通常我们使用 getter
get formArray()
{
return this.form.get('arrayName') as FormArray
}
还有我们的.html喜欢
<form [formGroup]="form">
<div formArrayName="arrayName">
<div *ngFor="let group of formArray.controls;let i=index"
[formGroupName]="i">
..here we are inside the formGroup, so use formControlName..
<input formControlName="prop1">
</div>
</div>
</form>
“关键”总是要有一个formGroup,并且在里面使用formControlName。在 FormGroup 中的典型 fromArray 中,我们使用 formArrayName
和 [fromGroupName]="i"
.
但是假设您有一个 FormArrays 的 FormArray。这管理一个数据,如
arrayName:[
[{row:1,col:1},{row:1,col2}]
[{row:2,col:1},{row:2,col2}]
]
要获取内部 FormArray,我们需要一个函数(我们不能使用 getter),例如
getInsideArrayForm(index:number)
{
return this.formArray.at(index) as FormArray
}
还有一个获取formGroup
getInsideFormGroup(i:number,j:number)
{
return this.getInsideArrayForm(i).at(j) as FormGroup
}
看看我们如何使用之前声明的函数
然后我们可以使用
<form [formGroup]="form">
<ng-container formArrayName="arrayName">
<!--see we iterate first over outher formArray.controls-->
<ng-container *ngFor="let array of formArray.controls;
let i=index">
<!--see how we use to loop the function
"getInsideArrayForm" and how we indicate "formGroup" using
the function getInsideFormGroup-->
<ng-container *ngFor="let group of getInsideArrayForm(i).controls;
let j=index" [formGroup]="getInsideFormGroup(i,j)>
..here we are inside the FormGroup..
<input formControlName="row">
<input formControlName="col">
</ng-container>
<ng-container>
</ng-container>
</form>
注意:我使用 FormArrays 的 FormArray,以及 FormGroup 中的第一个 FormArray,没有人强迫我们使用 FormGroup。我们可以直接使用 FormArray 来管理数据,例如
[
[{row:1,col:1},{row:1,col2}]
[{row:2,col:1},{row:2,col2}]
]
只是,记住获取FormGroup是必要的,但是我们可以去掉“
在我们的例子中,我们有一个“简单的”FormGroups 的 formArray。 “难”的是formArray是按tab分割的,但是“结构”总是一样的
我在重要的部分写了评论.html
<div class="section">
<div class="section__content container__shadow mx-3">
<h2 class="section__title">
{{ test.description }} <span> <i class="bx bx-test-tube"></i></span>
</h2>
<!--here declare the [formGroup]="resultForms"-->
<form *ngIf="resultsForm" autocomplete="off" [formGroup]="resultsForm">
<!--and create a div with formArrayName-->
<div formArrayName="results">
<mat-tab-group mat-align-tabs="center" #matGroup>
<mat-tab
*ngFor="let process of processes; let i = index"
label="{{ process.description }}"
>
<div class="text-center col-md-12" style="overflow: hidden;">
<h2 class="section__subtitle">{{ process.description }}</h2>
<div class="row">
<ng-container>
<!--instead iterate over tasks, we iterate
over formArray.controls
NOT over tasks (let task of tasks)
-->
<ng-container
*ngFor="let group of formArray.controls;
let i = index"
>
<!--and we use [formGroupName]="i"
I put in another div because we use this div to
show or not is "tasks[i]==process.id"
-->
<div
[formGroupName]="i"
*ngIf="tasks[i].psychological_processes_id==process.id"
class="col-12 col-md-6"
>
<div class="form-div">
<!--we use tasks[i].description-->
<label for="gender" class="form-tag"
>{{ tasks[i].description }} *</label
>
<!--in select we use formControlName="score"-->
<select
class="custom-select"
formControlName="score"
required
>
<!--see how you indicate that you should
"Seleccionar puntaje", the [value]="null"
makes that works the Validators.required
but when create the formControl we need use
score: new FormControl(null, [Validators.required]),
-->
<option selected hidden disabled [value]="null">
Seleccionar puntaje...
</option>
<!-- use [ngValue] (not only value)
if we want to get a number,
else we get a string-->
<option [ngValue]="1">1</option>
<option [ngValue]="2">2</option>
<option [ngValue]="3">3</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
</div>
...button next...
...button save...
</div>
</mat-tab>
</mat-tab-group>
</div>
</form>
</div>
</div>
我想为分数中数组的每个元素创建并绑定一个 formControl
我尝试这样做,但出现控制台错误:
找不到路径为:'crime_types -> 0
的控件
找不到带有路径的控件:'crime_types -> 1 -> score'
public resultsForm: FormGroup;
constructor(
private _formBuilder: FormBuilder,
) {
this.resultsForm = this._formBuilder.group({
crime_types: this._formBuilder.array([])
});
for (let i = 0; i < this.tasks.length; i++) {
this.formArrayCrimeType.push(
this._formBuilder.group({
psychological_tasks_id: new FormControl(this.tasks[i].id),
patients_id: new FormControl(this.patientId),
score: new FormControl('', [Validators.required]),
})
);
}
}
public get formArrayCrimeType(): FormArray {
return this.resultsForm.get("crime_types") as FormArray;
}
public getNumber(): number {
this.numb = this.numb + 1;
return this.numb;
}
模板
<ng-container formArrayName="crime_types">
<ng-container *ngFor="let task of tasks" [formGroupName]="getNumber()">
<div *ngIf="task.psychological_processes_id == process.id" class="col-12 col-md-6">
<div class="form-div">
<label for="gender" class="form-tag">{{task.description}} *</label>
<select formControlName="score" class="custom-select" required>
<option selected disabled value="">Seleccionar puntaje...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">2</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
当我们有一个 FormGroups 的 FormArray 时,通常我们使用 getter
get formArray()
{
return this.form.get('arrayName') as FormArray
}
还有我们的.html喜欢
<form [formGroup]="form">
<div formArrayName="arrayName">
<div *ngFor="let group of formArray.controls;let i=index"
[formGroupName]="i">
..here we are inside the formGroup, so use formControlName..
<input formControlName="prop1">
</div>
</div>
</form>
“关键”总是要有一个formGroup,并且在里面使用formControlName。在 FormGroup 中的典型 fromArray 中,我们使用 formArrayName
和 [fromGroupName]="i"
.
但是假设您有一个 FormArrays 的 FormArray。这管理一个数据,如
arrayName:[
[{row:1,col:1},{row:1,col2}]
[{row:2,col:1},{row:2,col2}]
]
要获取内部 FormArray,我们需要一个函数(我们不能使用 getter),例如
getInsideArrayForm(index:number)
{
return this.formArray.at(index) as FormArray
}
还有一个获取formGroup
getInsideFormGroup(i:number,j:number)
{
return this.getInsideArrayForm(i).at(j) as FormGroup
}
看看我们如何使用之前声明的函数
然后我们可以使用
<form [formGroup]="form">
<ng-container formArrayName="arrayName">
<!--see we iterate first over outher formArray.controls-->
<ng-container *ngFor="let array of formArray.controls;
let i=index">
<!--see how we use to loop the function
"getInsideArrayForm" and how we indicate "formGroup" using
the function getInsideFormGroup-->
<ng-container *ngFor="let group of getInsideArrayForm(i).controls;
let j=index" [formGroup]="getInsideFormGroup(i,j)>
..here we are inside the FormGroup..
<input formControlName="row">
<input formControlName="col">
</ng-container>
<ng-container>
</ng-container>
</form>
注意:我使用 FormArrays 的 FormArray,以及 FormGroup 中的第一个 FormArray,没有人强迫我们使用 FormGroup。我们可以直接使用 FormArray 来管理数据,例如
[
[{row:1,col:1},{row:1,col2}]
[{row:2,col:1},{row:2,col2}]
]
只是,记住获取FormGroup是必要的,但是我们可以去掉“
在我们的例子中,我们有一个“简单的”FormGroups 的 formArray。 “难”的是formArray是按tab分割的,但是“结构”总是一样的
我在重要的部分写了评论.html
<div class="section">
<div class="section__content container__shadow mx-3">
<h2 class="section__title">
{{ test.description }} <span> <i class="bx bx-test-tube"></i></span>
</h2>
<!--here declare the [formGroup]="resultForms"-->
<form *ngIf="resultsForm" autocomplete="off" [formGroup]="resultsForm">
<!--and create a div with formArrayName-->
<div formArrayName="results">
<mat-tab-group mat-align-tabs="center" #matGroup>
<mat-tab
*ngFor="let process of processes; let i = index"
label="{{ process.description }}"
>
<div class="text-center col-md-12" style="overflow: hidden;">
<h2 class="section__subtitle">{{ process.description }}</h2>
<div class="row">
<ng-container>
<!--instead iterate over tasks, we iterate
over formArray.controls
NOT over tasks (let task of tasks)
-->
<ng-container
*ngFor="let group of formArray.controls;
let i = index"
>
<!--and we use [formGroupName]="i"
I put in another div because we use this div to
show or not is "tasks[i]==process.id"
-->
<div
[formGroupName]="i"
*ngIf="tasks[i].psychological_processes_id==process.id"
class="col-12 col-md-6"
>
<div class="form-div">
<!--we use tasks[i].description-->
<label for="gender" class="form-tag"
>{{ tasks[i].description }} *</label
>
<!--in select we use formControlName="score"-->
<select
class="custom-select"
formControlName="score"
required
>
<!--see how you indicate that you should
"Seleccionar puntaje", the [value]="null"
makes that works the Validators.required
but when create the formControl we need use
score: new FormControl(null, [Validators.required]),
-->
<option selected hidden disabled [value]="null">
Seleccionar puntaje...
</option>
<!-- use [ngValue] (not only value)
if we want to get a number,
else we get a string-->
<option [ngValue]="1">1</option>
<option [ngValue]="2">2</option>
<option [ngValue]="3">3</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
</div>
...button next...
...button save...
</div>
</mat-tab>
</mat-tab-group>
</div>
</form>
</div>
</div>