- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑
由于上面 Chellappan 的回答,问题的第一部分已经解决,但我遇到了其他问题,这让我做了一个可以在这里找到的 stackblitz: https://stackblitz.com/edit/angular-ivy-bzh3dh
问题是我无法正确检索从表单中选择的产品列表,因为它们都已输出:
"courses": [
{
"courseName": "Dessert",
"products": [
{
"product": true
},
{
"product": false
},
{
"product": null
}
]
我不知道如何能够检索类似的东西:
"courses": [
{
"courseName": "Dessert",
"products": [
{
"Crumble aux pommes": true
},
{
"Mousse au chocolat maison": false
},
{
"Riz au lait": false
}
]
第二个问题是我的复选框的标签不是独立的。如果我添加一个新的“类(class)”并选择一些产品,其他类(class)中所有复选框的标签也会更改。
我希望我的帖子不要太乱,我不会经常在 Stack Overflow 上编辑消息
编辑结束
我有一个带有嵌套形式数组的 react 形式来描述包含多个类(class)的菜单每门类(class)都包含几种产品,但我不知道如何让它发挥作用。我的实际问题是我无法恢复我的二级控件。
这是菜单的json结构:
{
"name": "",
"description": "",
"price": "",
"courses": [
{
"courseName": "",
"products": [
{
"product": ""
}
]
}
]
}
我以这个项目为例:
为了便于阅读,这是我的简化形式:
<form [formGroup]="menuForm" (ngSubmit)="onSubmit(menuForm)">
<div class="form-group">
<input
class="form-control"
formControlName="name"
type="text">
</div>
<div class="form-group">
<textarea
class="form-control"
formControlName="description"></textarea>
</div>
<div class="col-md-3 form-group">
<input
class="form-control"
formControlName="price"
type="number">
</div>
</div>
<div class="row col-md-12">
<button class="btn btn-outline-dark" type="button" (click)="onAddCourse()">
Add course
</button>
</div>
<div class="row" formArrayName="courses">
<div *ngFor="let course of getCourses(menuForm); let i = index"
[formGroupName]="i">
<div class="...">
<select
class="form-control"
formControlName="courseName">
<option *ngFor="let course of courses">{{course.name}}</option>
</select>
<button type="button" class="mt-2 btn btn-outline-dark" (click)="onLoadProducts(i)">
Load Products // <- will load products that have course Name selected form the input 'courseName'above
</button>
<div class="row" formArrayName="products">
<div class="col-md-12"
*ngFor="let product of getProducts(menuForm); let j = index"
[formGroupName]="j">
<input class="form-check-input" type="checkbox" id="product{{i}}-{{j}}"
formControlName="product"/>
<label class="form-check-label" for="product{{i}}-{{j}}">product</label>
</div>
</div>
</div>
</div>
</div>
<br>
<div class="row col-md-12">
<button class="btn btn-success mr-1" type="submit" [disabled]="!menuForm.valid">{{buttonSubmitLabel}}</button>
</div>
</form>
这是我在 TS 中的表单初始化:
export class MenuEditComponent implements OnInit {
menuForm: FormGroup;
menu: MenuModel;
categories: CategoryModel[];
...
constructor(private router: Router,
private route: ActivatedRoute,
private productService: ProductService,
private menuService: MenuService) { }
ngOnInit(): void {
this.productService.getCategories().subscribe(
result => {
this.categories = result;
},
error => {
console.log(error);
this.categories = [];
});
this.initForm();
}
initForm() {
this.menuForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.maxLength(100)]),
description: new FormControl('', Validators.maxLength(255)),
price: new FormControl('', [Validators.required, Validators.min(0)]),
courses: new FormArray([
this.initCourse(),
])
});
}
initCourse() {
return new FormGroup({
courseName: new FormControl(''),
products: new FormArray([
this.initProduct()
])
});
}
initProduct() {
return new FormGroup({
product: new FormControl('')
});
}
getCourses(form) {
return form.controls.courses.controls;
}
getProducts(form) {
return form.controls.products.controls;
}
onAddCourse() {
const control = this.menuForm.get('courses') as FormArray;
control.push(this.initCourse());
}
onLoadProducts(i: number) {
console.log(this.menuForm.controls.courses);
const courseControl = this.menuForm.get('courses') as FormArray;
const course = courseControl.at(i).get('courseName').value;
console.log(course);
const products: ProductModel[] = this.mapProducts.get(course);
console.log(products);
const productControl = this.menuForm.get('courses').get[i].get('products') as FormArray;
onSubmit(menuForm: FormGroup) {
...
}
...
}
如果我这样离开后端,我会出错:
Cannot read property 'controls' of undefined at MenuEditComponent.getProducts
因此我的“产品”FormArray 未初始化。如果我这样做:
getProducts(form) {
return form.controls.products?.controls;
}
我不再有错误,但我无法访问产品 formControls。如果我尝试:
onLoadProducts(i: number) {
const courseControl = this.menuForm.get('courses') as FormArray;
const course = courseControl.at(i).get('courseName').value;
const products: ProductModel[] = this.mapProducts.get(course);
const productControl = this.menuForm.get('courses').get[i].get('products') as FormArray;
//On the last line i get a 'Cannot read property 'get' of undefined'
...
}
我做错了什么?为什么我的“产品”FormArray 没有初始化?
非常感谢您的帮助!
最佳答案
我查看了您的 stackblitz,并对其进行了修改并使其正常工作。您不需要将 formControlName 与您的产品绑定(bind),因为您不是从前端 UI 设置它们,而只是选择它们。我在类 ProductModel
中添加了一个名为 added
的字段,然后我刚刚为复选框实现了 change
事件以将其标记为真或假.
您还可以看到我是如何为产品设置值(value)的。当您点击 Load Products
按钮时,您将添加空的 FormGroup
但您还应该在其中设置 product
控件与产品数据。您可以在代码中看到我在 LoadProducts 方法中的操作方式
之后,您可以在产品循环中看到我是如何获得产品字段的。循环实际上给了我们 FormGroup 我们必须从中获取产品字段值
这是正在完成这项工作的堆栈 Blitz 。
https://stackblitz.com/edit/angular-ivy-ohwv1v
这部分你可以特别注意
if (this.productsByCategory) {
this.productsByCategory.forEach(
(product) => {
const productForm: FormGroup = this.initProduct();
productForm.controls.product.setValue(product);
control.push(productForm);
});
}
创建 productFormGroup 后,您还应该在其中设置产品。像 productForm.controls.product.setValue(product);
然后在前端你可以看到
<div *ngFor="let p of getProducts(course); let j = index" [formGroupName]="j">
<input type="checkbox" id="product{{i}}-{{j}}" [value]="p.value.product.added" (change)="p.value.product.added = !p.value.product.added"/>
<label for="product{{i}}-{{j}}">{{p.value.product.name}}</label>
</div>
您应该将值绑定(bind)到产品的添加属性,并且名称也应该显示在产品对象的标签内。
希望这将帮助您进一步进行。
And the second problem is that the labels of my checkboxes are not independent. If i add a new 'course' and that i select some products, the labels of all checkboxes in other courses are changed too.
上述问题已解决
I don't know how to be able to retrieve something like:
而不是 productName: true/false
你有整个产品对象可用,added
字段将标记它的 checked/unchecked
关于angular - 如何在 Angular 9 Reactive Form 中获取嵌套的 FormArray 控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62257541/
这是我想要完成的: 在一个页面中,用户将能够上传他们对某些外汇对的保护。因此,用户可以选择不同的时间范围来上传他们的图像分析。我的表格很简单: dataForm: FormGroup; this.da
我不知道如何重置 FormArray 的单个字段,例如: myForm = this.fb.group( { title: ["", [Validators.r
我正在尝试在 formarray 中实现 formarray 但它不起作用,下面也尝试过但不起作用。 How to get FormArrayName when the FormArray is ne
我用 ControlValueAccessor 构建了一个自定义输入组件,它非常适合添加标签作为选择。 ( Stackblitz ) 我的问题是: 当我在表单中实现组件时(城市和州控件) 通过选择一些
我认为这可能是响应式(Reactive)表单的一个错误。如果有经验丰富的 Angular 专家提供帮助,我将不胜感激。 症状:无法在给定时间输入超过 1 个字符。 出现情况:当输入是 FormArra
如何解决下面提到的错误: Type 'FormArray' is not assignable to type 'any[]'. Property 'includes' is missing in t
我有一个表单,其中一个控件是 formGroups 的 formArray。我将自定义验证器设置为 formGroups 中的一些控件。验证器工作正常,如果我在某些控件无效时检查 formArray
我想在表单中添加自定义验证器,以防止 mat-step 切换到下一步。当我使用 FormGroups 时一切正常,但当我必须使用 FormArray 时无法实现验证。 我已经尝试了至少两种在表单初始化
我想要多条错误消息,但不知道该怎么做......?在这里,我需要分别验证每个步骤,这就是我使用此步进器的原因 Em
我已经实现了一个 stackblitz,您可以在其中使用一些配置创建一个动态表单。一切正常,直到您使用 FormArray .什么想法?基本上,您的配置文件中可以有许多不同类型的字段。例如 check
我想用 FormArray 创建一个可编辑的表格。 为此,我有 results在表中呈现的属性。 用 FormArray 数据初始化它的正确方法是什么? results: Array; tableFo
我有一个动态大小的项目。对于每个我想生成一个复选框的项目。 我认为最好的方法是使用 FormArray。 但是我无法设置任何其他属性来指定动态复选框的标签。 items: Array = ['Bana
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
这是我的表单组: this.productGroup = this.fb.group({ name: ['', Validators.compose([Validators.required, V
我在 Angular 6 中使用了响应式(Reactive)形式。这种响应式(Reactive)形式包含一个名为 instruments 的 FormGroup,它是一个 FormArray。 我收到
我的 Angular 5/Angular Material 应用程序中有这个 FormArray: this.form = new FormGroup({ customerNumberC
我有一个 PhoneNumbersFormComponent 其模板如下所示: 我想通过 angular-cli 的 ng g component
我用 angular2 和 typescript 构建了一个表单。我尝试动态添加复选框列表,但它对我不起作用,我的错误在哪里? 模板代码:
我有在 FormBuilder 的帮助下构建的 Angular 表单。 Form 包含一个 FormArray,它具有用户想要的任意多的字段。我已经为字段设置了验证器 this.fb.array([t
我创建了一个自定义验证器来验证我的 FormArray 中的唯一性。当特定的值已经在数组中时,我想显示错误。 问题是它没有按预期工作。 实际行为: 重现步骤: 添加 3 个“输入”- 地址; 填写输入
我是一名优秀的程序员,十分优秀!