html - 使用 *ngFor 并从中提交值的动态表单
问题描述
我有一个stackblitz作为指导。
我想显示我单击“编辑”按钮的材料卡列表,我可以在其中编辑文本字段,当我单击“保存”图标时,它当然会通过触发功能等来保存。
然而,我正在努力掌握这一切在 Angular 中是如何工作的以及我的应用程序的 Material 特性。
html
<form id="myForm" [formGroup]="thisIsMyForm">
<mat-card [formGroup]="x" *ngFor="let x of data; let i = index">
<mat-form-field>
<label for="{{x.name}}">Name</label>
<input formControlName="name" id="{{x.name}}" matInput value="{{x.name}}">
</mat-form-field>
<mat-form-field>
<label for="{{x.type}}">Type</label>
<input formControlName="type" id="{{x.type}}" matInput value="{{x.type}}"/>
</mat-form-field>
</mat-card>
</form>
ts
import { Component, ViewChild } from '@angular/core';
import {MatSnackBar} from '@angular/material';
import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
thisIsMyForm: FormGroup
data = [
{name:"one", type:"one"},
{name:"two", type:"two"},
{name:"three", type:"three"},
];
constructor(private formBuilder: FormBuilder) {}
onSubmit() {
// Here I would like to be able to access the values of the 'forms'
}
}
解决方案
您肯定正在深入研究,尝试在 an 范围内构建动态响应式表单*ngFor
是一项挑战。我会尽我所能引导你完成它。
您将需要为控件创建一个数组,在您的构造函数中将您的表单设置创建formArrayName
为一个空数组,使用this.formBuild.array([])
...随意调用它,我只是用于formArrayName
演示目的。
使用空数组调用实例化表单后this.buildForm()
constructor(private formBuilder: FormBuilder) {
this.thisIsMyForm = new FormGroup({
formArrayName: this.formBuilder.array([])
})
this.buildForm();
}
在您buildForm()
迭代您的data[]
并为每个索引推送控件时,同时分配默认值和禁用的默认状态。
buildForm() {
const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
Object.keys(this.data).forEach((i) => {
controlArray.push(
this.formBuilder.group({
name: new FormControl({ value: this.data[i].name, disabled: true }),
type: new FormControl({ value: this.data[i].type, disabled: true })
})
)
})
console.log(controlArray)
}
请注意: console.log(controlArray.controls) 会产生以下输出...每个索引都是一个带有两个控件的 FormGroupname
和type
0: FormGroup
1: FormGroup
2: FormGroup
在您的 html 中,您将需要建立一个模仿thisIsMyForm
您刚刚创建的容器层次结构。
- 家长:
thisIsMyForm
- 孩子:
formArrayName
- 孙子:
i as formGroupName
孙子很重要,因为它与controlArray.controls
上一步中的控制台日志匹配
<form id="myForm" [formGroup]="thisIsMyForm">
<div [formArrayName]="'formArrayName'">
<mat-card *ngFor="let x of data; let i = index">
<div [formGroupName]="i">
根据控件禁用状态创建编辑和保存按钮
<button *ngIf="formControlState(i)" (click)="toggleEdit(i)">Enable Edit</button>
<button *ngIf="!formControlState(i)" (click)="toggleEdit(i)">Save</button>
在组件中创建方法以接收索引作为参数并处理逻辑以隐藏按钮和切换输入字段启用和禁用状态。
toggleEdit(i) {
const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
if(controlArray.controls[i].status === 'DISABLED'){
controlArray.controls[i].enable()
}else{
controlArray.controls[i].disable()
}
}
formControlState(i){
const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
return controlArray.controls[i].disabled
}
提交按钮时,console.log 的表单值在单击时...在任何输入 formControls 处于启用状态时也禁用按钮。
<button [disabled]="thisIsMyForm.get('formArrayName').enabled" (click)="onSubmit()">Submit Form</button>
onSubmit() {
// Here I would like to be able to access the values of the 'forms'
console.log(this.thisIsMyForm.value)
}
堆栈闪电战
https://stackblitz.com/edit/dynamic-form-ngfor-otbuzn?embed=1&file=src/app/app.component.ts
推荐阅读
- c# - Is there a way to alias a single, static (public) method in C#?
- r - RMarkdown: a way to compose a report from many mini-RMarkdown documents?
- regex - Regex: cut from second occurence of character to another character
- python - 使用 Python 创建关键字搜索词数组
- c - 当我使用 iso_c_binding 时未定义对“cos”的引用
- python - 在没有任何模块/库的情况下将列表列表写入 csv 文件
- http-headers - 使用 BrowserProxyMob 和 Selenium 时,部分请求缺少标头信息
- c++ - 运行 OpenMP 并行 for 循环时出现分段错误
- java - Gradle + JavaFX + 模块系统:项目模块从模块路径中消失?
- python - 使用 regex 和 .apply 从带有字符串对象的 pandas 数据框列中提取数字