我试图建立一个Angular Reactive表单,其中一个帐户可以添加许多学生。
该表格似乎有效。当您点击添加学生时,它会创建一个新学生,但您会在控制台上看到提示
错误错误:找不到路径为'studentsArray-> 1-> firstName的控件
以此类推。
app.component.html
<form [formGroup]="accountForm">
<div>
<input formControlName="firstName" placeholder="First name">
</div>
<div>
<input formControlName="lastName" placeholder="Last name">
</div>
<div>
<input formControlName="phone" placeholder="Phone">
</div>
<div>
<input formControlName="email" placeholder="Email">
</div>
<button (click)="addStudent()" *ngIf="!showStudentForm">Add Student</button>
<div formArrayName="studentsArray">
<div *ngFor="let student of studentsArray.controls; let i = index" [formGroupName]="i">
<input formControlName="firstName" placeholder="First Name">
<input formControlName="lastName" placeholder="Last Name">
<input formControlName="dob" placeholder="Date of Birth">
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
app.component.ts
import { Component, Input, OnChanges } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray, FormBuilder } …Run Code Online (Sandbox Code Playgroud) 我正在使用Angular 7和Angular Material实现一个注册页面。在此页面中,我使用密码输入组件,该组件获取对所使用的 FormGroup 的引用。外部组件处理逻辑部分(例如 FormGroup 的外观、FormControl 的定义方式以及每个输入的验证方式)。当我单击密码输入并单击其他位置/输入任何无效内容时,输入的错误消息会正确显示。但是,当我单击提交按钮而不触摸任何输入字段时,FormGroup 的 FormControl 会被验证(FormControl 甚至说它有错误)但不会被触摸,因此不会显示错误消息。
我已经研究过如何解决此行为。一些人建议在单击提交按钮后手动将所有表单控件设置为触摸状态。是的,这可行,但我希望有一个通用的解决方案,这样我就不必为将来的每种表单都这样做。
注册.组件.ts:
export class SignupComponent implements OnInit {
signupForm: FormGroup;
constructor() { }
ngOnInit() {
this.signupForm = new FormGroup({
'password': new FormControl('', [Validators.required]),
'contact': new FormControl('', [Validators.required])
});
}
onSubmit() {
console.log('Form validity: ' + this.signupForm.valid);
}
}
Run Code Online (Sandbox Code Playgroud)
注册.组件.html:
<mat-card class="signup-card">
<h1 class="signup-title">Sign up</h1>
<form [formGroup]="signupForm" #form="ngForm" (ngSubmit)="onSubmit()" fxLayout="column">
<!-- Password -->
<app-base-password-input [parentForm]="signupForm"></app-base-password-input>
<!-- Contact -->
<div class="signup-contact">
<mat-checkbox formControlName="contact" …Run Code Online (Sandbox Code Playgroud) 我有一个动态创建的表,它显示的数据如下:
<table>
<tr *ngFor="let product of products">
<td>{{product.name}}</td>
<td>{{product.description}}</td>
<td>{{product.value}}</td>
<!-- BELOW IS WHERE A NEW VALUE WILL BE ENTERED -->
<td><input type="text" value=""></td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
我读到处理这个问题的适当方法是使用 FormsArray。但我也读到,使用 FormsArray 的正确方法是获取其控件数组:
<table>
<tr *ngFor="let product of this.form.get('productCollection').controls; let i = index;"
[formGroupName]="i">
<td>{{product.name}}</td>
<td>{{product.description}}</td>
<td>{{product.value}}</td>
<!-- BELOW IS WHERE A NEW VALUE WILL BE ENTERED -->
<td><input type="text" formControlName="name"></td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)
问题是我无权访问此处的描述值。我还没有找到一种方法将其作为元数据传递给控件,以便我可以显示它。
那么问题是,对于这样的事情,哪种方法是正确的?是FormArray吗?它是一个 FormGroup 中的一组 FormControl 吗?或者每个表单控件都需要单独存在吗?我愿意接受有关如何开展这项工作的建议。
dynamic-forms angular angular-reactive-forms formarray formgroups
In the other examples at StackOverflow there are many questions about using FormGroups in FormArrays. But my question is the opposite.
FormArrays have a push method, that makes many things possible. FormGroups have indeed an addControl method for adding simple FormControls. Afaik FormGroups do not have addFormArray or addFormGroup method. Therefore I need your help.
Following situation:
this.myForm = this.fb.group({
id: this.fb.control([this.book.id]),
// or short form `id: [this.book.id],`
});
Run Code Online (Sandbox Code Playgroud)
Adding a simple control at a later point in time is …
当我的编辑表单加载时,我想用初始值填充表单数组。我的下拉选择选项被禁用,但它没有显示在垫选择中。
let selectedSpecs = this.editData.element.specifications;
this.spec = this.specForm.get('spec') as FormArray;
if (selectedSpecs.length != 0){
let selectedAttributeIds = [];
selectedSpecs.forEach((spec, i) => {
let attribute;
attribute = {'id': spec.itemDetailId, 'itemId':this.editData.element.itemId, 'name': spec.name};
this.spec.push(this.formBuilder.group({
attribute: attribute,
attributeSpec: spec.description
}));
selectedAttributeIds.push(spec.itemDetailId);
});
let attributes = [];
this.selectedCatAttributes.forEach((tempattribute) => {
let selected;
if (selectedAttributeIds.includes(tempattribute.id)) {
selected = true;
}else {
selected = false;
}
attributes.push(new Attribute(tempattribute, !selected));
});
this.attributeList.next(attributes);
}
<div formArrayName="spec" *ngFor="let spec of specForm.get('spec')['controls']; let i= index">
<div [formGroupName]="i">
<mat-card class="addShadow">
<button …Run Code Online (Sandbox Code Playgroud) javascript typescript formgroups angular6 angular-material-6
几天来,我一直在努力为我的用例找到一个好的模式。我有一个非常复杂的反应式表单,充满了嵌套组件,一些字段是必需的,某些字段可能会在特定条件下出现,等等……这给维护代码带来了巨大的问题。到目前为止,我使用的方法是将 formControl 传递给子组件并从那里填充,但是鉴于表单的大小,事情开始变得非常难以调试。此表单必须在提交整个表单时,对所有嵌套字段进行验证,并标记任何需要但尚未插入的字段。我一直在探索 2 种方法,但 2 种方法似乎都没有任何帮助:
我想知道是否有人对此类表格有任何经验,并能够就这种情况下的最佳做法提供一些指导。我使用 Control Container 做了一个非常简单的 stackblitz,只有一个子孩子,不幸的是我无法让它运行https://stackblitz.com/edit/angular-ivy-axbgr5
我在 Angular 10 应用程序中遇到问题,在初始化时将 formGroup 的状态传播到其父级。
问题:在组件初始化时,子表单的验证状态未正确传播到多个级别的父级中。
更准确地说,我有 3 个嵌套组件。它们都是表单,并且两个子级都实现 ControlValueAccessor。它们通过“formControlName”属性进行通信。最深的形式初始化错误(必填字段)。父级不会收到有效性状态(它仍然有效)。
这是问题的重现:
https://stackblitz.com/edit/ngx-sub-form-hzo8wj?file=src/app/app.component.ts
我希望“基本表单组”在初始化时无效。“级别 2”的有效性应在“基本表单组”中的“级别 1”然后“级别 1”中传播。
它可能来自正常的角度周期。
我在等待更好的解决方案时发现了一个 hack:
public ngAfterViewInit(): void {
this._injector.get(NgControl).control.updateValueAndValidity();
}
Run Code Online (Sandbox Code Playgroud)
在第一个角度周期后,我们手动重新启动子级对父级的验证。这是级联在所有子组件中的。
我怎样才能避免使用这个黑客?
我在角度4中创建了一个formGroup,其中用户和组织存储在对象中.现在我想使用这两个对象填充我的表单组.在我的ts中,我做了以下事情:
createForm(user: any) {
this.userForm = this.fb.group({
name: user.profileData.name,
email: user.profileData.email,
phone: user.profileData.mobileNumber,
orgForm: this.fb.group({
name: [ user.organisation.name , [Validators.required]]
})
});
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我正在做这样的事情:
<form [formGroup]="userForm" class="user-form" (ngSubmit)="onSubmit()" novalidate>
<div fxLayout="row">
<div fxLayout="column" fxFlex="50%">
<div class="form-group">
<md-input-container class="full-width">
<input mdInput placeholder="User Name" formControlName="name">
</md-input-container>
</div>
<div class="form-group">
<md-input-container class="full-width">
<input mdInput placeholder="User Email" formControlName="email">
</md-input-container>
</div>
<div class="form-group">
<md-input-container class="full-width">
<input mdInput placeholder="User Phone" formControlName="phone">
</md-input-container>
</div>
<div class="form-group">
<button md-raised-button type="submit" [disabled]="userForm.pristine">Save</button>
</div>
</div>
<div fxLayout="column" fxFlex="50%" formGroupName="orgForm">
<div …Run Code Online (Sandbox Code Playgroud) 当我们尝试使用 formGroup 时,我们会遇到一些错误。我需要一些关于表单组的解释。我想创建一个包含数据的表单组。数据需要逐行显示。 当我运行它时,我们使用 Angular 8 ,我收到此错误:
路径没有表单控件的值访问器:'rowDetails -> 0 -> no'
我有这个组件的构造函数:
constructor(
public fb: FormBuilder
) {
this.summaryForm = this.fb.group({
rowDetails: this.fb.array([])
})
}
Run Code Online (Sandbox Code Playgroud)
我有这个组件控制器:
ngOnInit() {
this.productList = (this.selectedReceiptBatch.incomeSummary as SaleSummary).sales;
this.summaryForm = this.fb.group({
rowDetails: this.fb.array(
this.productList.map(x=> this.fb.group({
'no': x.product.code,
'desc': x.product.productClass,
'numberx': [x.number.x],
'numbery': x.number.y,
'amountz': x.number.z,
'reference': [x.reference]
})
))
});
console.log(this.summaryForm);
this.formControlAvailable = true;
}
Run Code Online (Sandbox Code Playgroud)
HTML:
<div *ngIf="formControlAvailable">
<div>
<div [formGroup]="summaryForm">
<div formArrayName="rowDetails">
<div *ngFor="let row of summaryForm.controls.rowDetails.controls; let index = index">
<div [formGroupName]="index"> …Run Code Online (Sandbox Code Playgroud) 我正在使用 FormArray 来使用嵌套 FormControl。我的表格是这样的:
let form = new FormGroup({
name: new FormControl(),
email: new FormControl(),
Addresses : new FormArray([
new FormGroup({
building: new FormControl(),
society : new FormControl(),
}),
new FormGroup({
building: new FormControl(),
society : new FormControl(),
})
new FormGroup({
building: new FormControl(),
society : new FormControl(),
})
])
})
addNewAddress() {
let newAddress = new FormGroup({
building: new FormControl(),
society : new FormControl(),
});
this.form.get("addresses").push(newAddress)
}
Run Code Online (Sandbox Code Playgroud)
<div *ngFor="let controlGroup of form.get('addresses').controls; let i=index">
<ng-container [formGroup]="controlGroup"> …Run Code Online (Sandbox Code Playgroud) formgroups ×10
angular ×9
formarray ×5
angular6 ×2
forms ×2
javascript ×1
submit ×1
typescript ×1