angular 11 表单动态数据绑定
angular 11 form dynamic data binding
我有一个表单,其中有一对输入,一个用于名称,一个用于数字。所需的此类对的数量取决于用户输入,例如如果用户输入 5,它将生成 5 个这样的对。到目前为止,我可以使 UI 部分正常工作,例如它可以动态生成所需的对。问题是那些动态生成的输入对的数据绑定。因为它们是表单的一部分,所以我不能使用 [(ngModel)]
。我尝试使用 FormControlName
但由于每个输入对的动态特性,它不起作用;似乎每个 FormControl
都必须在组件初始化时创建。窗体中的其他控件未显示。
我有一种感觉,也许我以错误的方式处理这个问题,有没有 'angular' 的方法来做到这一点?
<form [formGroup]="projectForm">
<div>
Enter the number of jobs:<input type="number" formControlName="jobCounter2"><br>
<ng-container *ngFor="let i of [].constructor(projectForm.value.jobCounter2); let j = index">
<div>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="jobNames2[j]">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="jobSalary2[j]">
</ng-container>
</div>
</ng-container>
</div>
</form>
您可以使用FormArray
动态创建控件。监听 JobCounter 元素的变化事件然后你可以迭代并添加 FormControl
到 Jobs 数组。
import {
Component,
OnInit,
VERSION
} from "@angular/core";
import {
Form,
FormArray,
FormBuilder,
FormGroup
} from "@angular/forms";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
projectForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.projectForm = this.formBuilder.group({
jobCounter: [],
jobs: this.formBuilder.array([]) //<=== Create Empty array
});
}
onJobCounterChange(value) {
value = Number(value);
// Create the desired group based on user input
for (let i = 0; i < value; i++) {
let fb = this.formBuilder.group({
name: [""],
salary: [""]
});
(this.projectForm.controls.jobs as FormArray).push(fb);
}
}
onSubmit() {
console.log(this.projectForm.value);
}
}
<form [formGroup]="projectForm" (ngSubmit)="onSubmit()">
<div>
Enter the number of jobs:
<input type="number" formControlName="jobCounter" (change)="onJobCounterChange(projectForm.controls.jobCounter.value)"><br>
<ng-container formArrayName="jobs">
<div *ngFor="let job of projectForm.get('jobs')['controls']; let j = index" [formGroupName]="j">>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="name">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="salary">
</ng-container>
</div>
</ng-container>
<button>Show Values</button>
</div>
</form>
Working Example, You can also play here
我认为您的方法可以改进以获得更好的用户体验,请考虑一下
- 与您的方法相同,用户可以添加更多字段但不将此值绑定到表单
- 包括一个删除按钮
这就是您的 TS 文件的样子
projectForm = this.formBuilder.group({
jobs: this.formBuilder.array([])
});
get jobs() {
return this.projectForm.get("jobs") as FormArray;
}
deleteJobField(i) {
this.jobs.controls.splice(i, 1);
this.jobs.updateValueAndValidity()
}
addJobField($event) {
$event.preventDefault();
console.log( Array(this.additionalJobFields))
Array(this.additionalJobFields).fill(1).forEach(() => {
this.jobs.push(
this.formBuilder.group({
name: "",
salary: 0
})
);
});
this.additionalJobFields = null;
}
additionalJobFields = null;
在你的 html
<form [formGroup]="projectForm" (ngSubmit)="onSubmit()">
<div>
<ng-container formArrayName="jobs">
<div *ngFor="let job of jobs.controls; let j = index" [formGroupName]="j">>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="name">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="salary">
<button (click)='deleteJobField(j)' type="button">DEL</button>
</ng-container>
</div>
</ng-container>
<button>Show Values</button>
</div>
Add More Jobs:<input type="number" (keydown.enter)="addJobField($event)" [(ngModel)]="additionalJobFields" [ngModelOptions]="{standalone: true}"><br>
</form>
<pre>{{ projectForm.value | json }}</pre>
基本思路是,当用户在输入字段中输入一个值以添加更多职位并按下回车键时,我们会更新表单数组中的字段数。
我们还针对每个输入类别添加了一个删除按钮,并在单击时更新表单数组
我有一个表单,其中有一对输入,一个用于名称,一个用于数字。所需的此类对的数量取决于用户输入,例如如果用户输入 5,它将生成 5 个这样的对。到目前为止,我可以使 UI 部分正常工作,例如它可以动态生成所需的对。问题是那些动态生成的输入对的数据绑定。因为它们是表单的一部分,所以我不能使用 [(ngModel)]
。我尝试使用 FormControlName
但由于每个输入对的动态特性,它不起作用;似乎每个 FormControl
都必须在组件初始化时创建。窗体中的其他控件未显示。
我有一种感觉,也许我以错误的方式处理这个问题,有没有 'angular' 的方法来做到这一点?
<form [formGroup]="projectForm">
<div>
Enter the number of jobs:<input type="number" formControlName="jobCounter2"><br>
<ng-container *ngFor="let i of [].constructor(projectForm.value.jobCounter2); let j = index">
<div>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="jobNames2[j]">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="jobSalary2[j]">
</ng-container>
</div>
</ng-container>
</div>
</form>
您可以使用FormArray
动态创建控件。监听 JobCounter 元素的变化事件然后你可以迭代并添加 FormControl
到 Jobs 数组。
import {
Component,
OnInit,
VERSION
} from "@angular/core";
import {
Form,
FormArray,
FormBuilder,
FormGroup
} from "@angular/forms";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
projectForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.projectForm = this.formBuilder.group({
jobCounter: [],
jobs: this.formBuilder.array([]) //<=== Create Empty array
});
}
onJobCounterChange(value) {
value = Number(value);
// Create the desired group based on user input
for (let i = 0; i < value; i++) {
let fb = this.formBuilder.group({
name: [""],
salary: [""]
});
(this.projectForm.controls.jobs as FormArray).push(fb);
}
}
onSubmit() {
console.log(this.projectForm.value);
}
}
<form [formGroup]="projectForm" (ngSubmit)="onSubmit()">
<div>
Enter the number of jobs:
<input type="number" formControlName="jobCounter" (change)="onJobCounterChange(projectForm.controls.jobCounter.value)"><br>
<ng-container formArrayName="jobs">
<div *ngFor="let job of projectForm.get('jobs')['controls']; let j = index" [formGroupName]="j">>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="name">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="salary">
</ng-container>
</div>
</ng-container>
<button>Show Values</button>
</div>
</form>
Working Example, You can also play here
我认为您的方法可以改进以获得更好的用户体验,请考虑一下
- 与您的方法相同,用户可以添加更多字段但不将此值绑定到表单
- 包括一个删除按钮
这就是您的 TS 文件的样子
projectForm = this.formBuilder.group({
jobs: this.formBuilder.array([])
});
get jobs() {
return this.projectForm.get("jobs") as FormArray;
}
deleteJobField(i) {
this.jobs.controls.splice(i, 1);
this.jobs.updateValueAndValidity()
}
addJobField($event) {
$event.preventDefault();
console.log( Array(this.additionalJobFields))
Array(this.additionalJobFields).fill(1).forEach(() => {
this.jobs.push(
this.formBuilder.group({
name: "",
salary: 0
})
);
});
this.additionalJobFields = null;
}
additionalJobFields = null;
在你的 html
<form [formGroup]="projectForm" (ngSubmit)="onSubmit()">
<div>
<ng-container formArrayName="jobs">
<div *ngFor="let job of jobs.controls; let j = index" [formGroupName]="j">>
<ng-container style="width: 2px;">
<input type="text" placeholder="job name" formControlName="name">
</ng-container>
<ng-container style="width: 1px">
<input type="number" placeholder="job salary e.g. 3.4" formControlName="salary">
<button (click)='deleteJobField(j)' type="button">DEL</button>
</ng-container>
</div>
</ng-container>
<button>Show Values</button>
</div>
Add More Jobs:<input type="number" (keydown.enter)="addJobField($event)" [(ngModel)]="additionalJobFields" [ngModelOptions]="{standalone: true}"><br>
</form>
<pre>{{ projectForm.value | json }}</pre>
基本思路是,当用户在输入字段中输入一个值以添加更多职位并按下回车键时,我们会更新表单数组中的字段数。
我们还针对每个输入类别添加了一个删除按钮,并在单击时更新表单数组