Angular 5 个响应式表单 - 为 FormArray 传递复选框 ID
Angular 5 Reactive Forms - pass checkbox Id's for FormArray
我正在使用 Reactive Forms FormGroup、FormBuilder 和 FormArray。我有一个 FormArray,我想在其中循环一个外部数组,创建一个复选框列表,然后将这些复选框的 ID 传递给我的 FormArray。
我的组件打字稿看起来像:
export class AppComponent {
form: FormGroup;
sites = [ "site-1", "site-2", "site-3", "site-4" ];
constructor(private fb: FormBuilder){
}
ngOnInit() {
this.form = this.fb.group({
type: [ '', Validators.required ],
sites: this.fb.array([
this.fb.group({
siteId: [ '', Validators.required ]
})
])
})
}
}
还有我的 html...
<form [formGroup]="form">
<input type="checkbox" formControlName="type" id="type">
<label for="type">Type</label>
<div class="checkbox-group" style="margin-top:40px">
<div class="checkbox-wrap" id="productsContainer">
<input type="checkbox" id="all">
<label for="all">All mills</label>
<div *ngFor="let site of sites; let i = index">
<input type="checkbox" [id]="i" />
<label [for]="i"> {{ site }} </label>
</div>
</div>
</div>
</form>
我知道我需要将 formArrayName 传递到 html,但是当我尝试传递 formArrayName="sites" 然后使用我的 "i" 时出现控制台错误循环作为 formGroupName。我做错了什么?
这是具有完整设置的 StackBlitz...
https://stackblitz.com/edit/angular-rcfnwi?file=app%2Fapp.component.html
答案确实可行,但在我看来,它显然不是一个表格数组。
当我们进行一系列检查时,我们必须了解有两个独立的概念:表格和数据。是的,这两个概念不一定相等。
我选择创建这样的表格
//we create a FormGroup array transform the array "this.sites"
const controls:FormGroup[]=this.sites.map(x=>{
return this.fb.group({
site:false
})
});
//in this.form I use this array of FormGroup
this.form = this.fb.group({
type: ['', Validators.required],
sites: this.fb.array(controls)
})
嗯,当我们制作表格时,form.value可以像
{
"type": "",
"sites": [
{ "site": false }, { "site": true }, { "site": false }, { "site": true }
]
}
然后,在提交中我们必须将form.value转换为我们喜欢的数据
submit(form: FormGroup) {
if (form.valid) {
//create an array of sites
let sites: string[] = [];
let i: number = 0;
form.value.sites.forEach((x:any) => {
if (x.site)
sites.push(this.sites[i]);
i++;
});
//Our data will be
let data = {
type: form.value.type,
sites: sites
}
console.log(data);
}
}
最后,表格:
<form [formGroup]="form" (submit)="submit(form)" novalidate">
<input formControlName="type">
<div formArrayName="sites" *ngFor="let site of form?.get('sites').controls;let i=index">
<div [formGroupName]="i">
<--!see that formControlName is "site"
and the labels of the check use the array this.sites -->
<input type="checkbox" formControlName="site" /> {{sites[i]}}
</div>
</div>
<button>send</button>
</form>
所有人都在问为什么,它是什么?所有的事情都必须太复杂?我的回答是没那么复杂。此外,想象一下如何用数据填充表单。
//if data={type:"a",sites:["site-2","site-4"], we create the form like
const controls:FormGroup[]=this.sites.map(x=>{
return this.fb.group({
site:data.sites.indexOf(x)>=0; //true or false
})
});
this.form = this.fb.group({
type: [data.type, Validators.required],
sites: this.fb.array(controls)
})
您需要使用与站点列表中的项目对应的内部dividual FormControl 填充 FormArray。在我的 fork 示例中,我在 FormGroup (https://stackblitz.com/edit/angular-hilz9h) 的初始化中完成了此操作,方法是映射站点数组并生成默认值为 false(未选中)的 FormControls。我还删除了围绕站点 FormArray 的嵌入式 FormGroup 以使其更简单。然后我将 formArrayName 指令添加到包装 div 中,其字符串属性对应于 ts 文件中 FormArray 的 'sites' 名称。最后,我添加了一个 [formControlName] 指令并将每个输入的 ngFor 索引传递给它,以对应于 FormArray 控件的数组索引。 FormArrays 在内部通过索引跟踪它们的控件。
所以,您的 ngOnInit 现在看起来像:
ngOnInit() {
this.form = this.fb.group({
type: [ '', Validators.required ],
sites: this.fb.array(this.sites.map(s => this.fb.control(false)),
[ Validators.required ])
})
}
您的 html 文件现在看起来像:
<form [formGroup]="form">
<input type="checkbox" formControlName="type" id="type">
<label for="type">Type</label>
<div class="checkbox-group" style="margin-top:40px">
<div class="checkbox-wrap" id="productsContainer" formArrayName="sites">
<input type="checkbox" id="all">
<label for="all">All mills</label>
<div *ngFor="let site of sites; let i = index">
<input type="checkbox" [id]="i" [formControlName]="i"/>
<label [for]="i"> {{ site }} </label>
</div>
</div>
</div>
</form>
<pre> {{ form.value | json }}</pre>
我正在使用 Reactive Forms FormGroup、FormBuilder 和 FormArray。我有一个 FormArray,我想在其中循环一个外部数组,创建一个复选框列表,然后将这些复选框的 ID 传递给我的 FormArray。
我的组件打字稿看起来像:
export class AppComponent {
form: FormGroup;
sites = [ "site-1", "site-2", "site-3", "site-4" ];
constructor(private fb: FormBuilder){
}
ngOnInit() {
this.form = this.fb.group({
type: [ '', Validators.required ],
sites: this.fb.array([
this.fb.group({
siteId: [ '', Validators.required ]
})
])
})
}
}
还有我的 html...
<form [formGroup]="form">
<input type="checkbox" formControlName="type" id="type">
<label for="type">Type</label>
<div class="checkbox-group" style="margin-top:40px">
<div class="checkbox-wrap" id="productsContainer">
<input type="checkbox" id="all">
<label for="all">All mills</label>
<div *ngFor="let site of sites; let i = index">
<input type="checkbox" [id]="i" />
<label [for]="i"> {{ site }} </label>
</div>
</div>
</div>
</form>
我知道我需要将 formArrayName 传递到 html,但是当我尝试传递 formArrayName="sites" 然后使用我的 "i" 时出现控制台错误循环作为 formGroupName。我做错了什么?
这是具有完整设置的 StackBlitz...
https://stackblitz.com/edit/angular-rcfnwi?file=app%2Fapp.component.html
答案确实可行,但在我看来,它显然不是一个表格数组。 当我们进行一系列检查时,我们必须了解有两个独立的概念:表格和数据。是的,这两个概念不一定相等。
我选择创建这样的表格
//we create a FormGroup array transform the array "this.sites"
const controls:FormGroup[]=this.sites.map(x=>{
return this.fb.group({
site:false
})
});
//in this.form I use this array of FormGroup
this.form = this.fb.group({
type: ['', Validators.required],
sites: this.fb.array(controls)
})
嗯,当我们制作表格时,form.value可以像
{
"type": "",
"sites": [
{ "site": false }, { "site": true }, { "site": false }, { "site": true }
]
}
然后,在提交中我们必须将form.value转换为我们喜欢的数据
submit(form: FormGroup) {
if (form.valid) {
//create an array of sites
let sites: string[] = [];
let i: number = 0;
form.value.sites.forEach((x:any) => {
if (x.site)
sites.push(this.sites[i]);
i++;
});
//Our data will be
let data = {
type: form.value.type,
sites: sites
}
console.log(data);
}
}
最后,表格:
<form [formGroup]="form" (submit)="submit(form)" novalidate">
<input formControlName="type">
<div formArrayName="sites" *ngFor="let site of form?.get('sites').controls;let i=index">
<div [formGroupName]="i">
<--!see that formControlName is "site"
and the labels of the check use the array this.sites -->
<input type="checkbox" formControlName="site" /> {{sites[i]}}
</div>
</div>
<button>send</button>
</form>
所有人都在问为什么,它是什么?所有的事情都必须太复杂?我的回答是没那么复杂。此外,想象一下如何用数据填充表单。
//if data={type:"a",sites:["site-2","site-4"], we create the form like
const controls:FormGroup[]=this.sites.map(x=>{
return this.fb.group({
site:data.sites.indexOf(x)>=0; //true or false
})
});
this.form = this.fb.group({
type: [data.type, Validators.required],
sites: this.fb.array(controls)
})
您需要使用与站点列表中的项目对应的内部dividual FormControl 填充 FormArray。在我的 fork 示例中,我在 FormGroup (https://stackblitz.com/edit/angular-hilz9h) 的初始化中完成了此操作,方法是映射站点数组并生成默认值为 false(未选中)的 FormControls。我还删除了围绕站点 FormArray 的嵌入式 FormGroup 以使其更简单。然后我将 formArrayName 指令添加到包装 div 中,其字符串属性对应于 ts 文件中 FormArray 的 'sites' 名称。最后,我添加了一个 [formControlName] 指令并将每个输入的 ngFor 索引传递给它,以对应于 FormArray 控件的数组索引。 FormArrays 在内部通过索引跟踪它们的控件。
所以,您的 ngOnInit 现在看起来像:
ngOnInit() {
this.form = this.fb.group({
type: [ '', Validators.required ],
sites: this.fb.array(this.sites.map(s => this.fb.control(false)),
[ Validators.required ])
})
}
您的 html 文件现在看起来像:
<form [formGroup]="form">
<input type="checkbox" formControlName="type" id="type">
<label for="type">Type</label>
<div class="checkbox-group" style="margin-top:40px">
<div class="checkbox-wrap" id="productsContainer" formArrayName="sites">
<input type="checkbox" id="all">
<label for="all">All mills</label>
<div *ngFor="let site of sites; let i = index">
<input type="checkbox" [id]="i" [formControlName]="i"/>
<label [for]="i"> {{ site }} </label>
</div>
</div>
</div>
</form>
<pre> {{ form.value | json }}</pre>