node.js - Angular 8:基于组件在html中动态设置formControlName
问题描述
在 db 表中,我有“key_name”,它在 API 中成功返回并且运行良好。
我想要做的是将这些字段值设置为formControlName
html 和组件中的值,我使用的是响应式表单,所以我尝试过formArrayName
。
基于更改事件,我正在推送新formControl
的categoryArray
并将其键分配为 db 字段的值。
这是我的 HTML:
<div class="col-md-6">
<div formArrayName="categoryArray" *ngFor="let type of types; let k = index">
<div [formGroupName]="k">
<div class="form-group">
<label>Select {{ type.cat_name }}</label>
<select class="form-control custom-select"
(change)="onChangeType($event.target.value)"
formControlName="{{ type.key_name }}" >
<option value="">-- Select --</option>
<option *ngFor="let type of types" [value]="type.category_id">
{{type.cat_name}}
</option>
</select>
</div>
</div>
</div>
</div>
组件.ts:
onChangeCategory(id) {
if(id) {
this.artistService.fetchTypeAndSubTypes(id).subscribe(res => {
if (res.status == 200) {
this.types = res.data
this.addInNewCategory(this.types)
}
})
} else {
this.types = null
this.subTypes = null
}
}
get category(): FormArray {
return <FormArray>this.uploadArtWorkForm.controls.categoryArray;
}
addInNewCategory(types) {
let obj = {}
types.forEach(element => {
obj[element['key_name']] = [null, [Validators.required]]
});
console.log("obj", obj)
this.category.push(
this.formBuilder.group(obj)
);
}
我要存档的是,基于 1 级类别选择,所有 2 级类别都将显示为动态 HTML 下拉列表,其子类别列表在下拉列表中。
我得到的错误:
ERROR Error: Cannot find control with path: 'categoryArray -> 1'
ERROR Error: Cannot find control with path: 'categoryArray -> 1 -> metal'
编辑: 设置表单控件名称后,如何设置每个新创建的下拉列表的值?我需要从数据库中获取它。
这里是 Stackblitz: https ://stackblitz.com/edit/dyncamic-populating-dropdown
提前致谢
解决方案
尝试自己修改代码,至少修复了以下错误:
ERROR 错误:找不到带有路径的控件:'categoryArray -> 1'
ERROR 错误:找不到带有路径的控件:'categoryArray -> 1 -> metal'
但是您仍然需要使用我的解决方案进行改进。
修改你的 app.component.html 如下:
<form [formGroup]="uploadArtWorkForm" (ngSubmit)="addUploadArtWorkForm();">
<div class="col-md-6">
<div class="form-group">
<label>Select Category:</label>
<select class="form-control custom-select" formControlName="cat_id" [ngClass]="{'is-invalid': uploadArtWorkForm.controls['cat_id'].invalid && (uploadArtWorkForm.controls['cat_id'].dirty || uploadArtWorkForm.controls['cat_id'].touched || isFormSubmitted) }" (change)="onChangeCategory($event, $event.target.value)">
<option value="">-- Select --</option>
<option *ngFor="let category of parentCategories" [value] ="category.category_id">
{{category.cat_name}}
</option>
</select>
<div class="invalid-feedback" *ngIf="uploadArtWorkForm.controls['cat_id'].errors">
<div *ngIf="uploadArtWorkForm.controls['cat_id'].errors.required">Category is
required.</div>
</div>
</div>
</div>
<div class="col-md-6" formArrayName="categoryArray" *ngIf="uploadArtWorkForm.get('categoryArray')['controls'].length > 0">
<div *ngFor="let item of uploadArtWorkForm.get('categoryArray')['controls']; let k = index">
<div [formGroup]="item">
<div class="form-group ">
<label>Select {{ types[k].cat_name }}</label>
<select class="form-control custom-select" [class]="types[k].key_name" (change)="onChangeType($event.target.value)" formControlName="{{ types[k].key_name }}" *ngIf="types[k].cat_name == 'Type'">
<option value="">-- Select --</option>
<option *ngFor="let type of catTypeValue" [value]="type.category_id">
{{type.cat_name}}
</option>
</select>
<select class="form-control custom-select" [class]="types[k].key_name" (change)="onChangeType($event.target.value)" formControlName="{{ types[k].key_name }}" *ngIf="types[k].cat_name == 'Metal'">
<option value="">-- Select --</option>
<option *ngFor="let type of catMetalValue" [value]="type.category_id">
{{type.cat_name}}
</option>
</select>
<select class="form-control custom-select" [class]="types[k].key_name" (change)="onChangeType($event.target.value)" formControlName="{{ types[k].key_name }}" *ngIf="types[k].cat_name == 'Gems'">
<option value="">-- Select --</option>
<option *ngFor="let type of catGemsValue" [value]="type.category_id">
{{type.cat_name}}
</option>
</select>
</div>
</div>
</div>
</div>
</form>
和 app.component.ts 如下:
import { Component } from "@angular/core";
import { FormGroup, FormBuilder, Validators, FormArray, FormControl } from "@angular/forms";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
uploadArtWorkForm: any;
uploadArtWorkForm1: any;
isFormSubmitted: boolean = false;
parentCategories = [
{"parent_id":0,"cat_name":"Jewelry","category_id":1},
{"parent_id":0,"cat_name":"Painting","category_id":16},
{"parent_id":0,"cat_name":"Photograph","category_id":22}];
types;
subTypes;
//below value will be displayed in Select Type dropdown
catTypeValue = [
{"parent_id":2,"cat_name":"Anklets","category_id":3,"key_name":"anklets"},
{"parent_id":2,
"cat_name":"Body",
"category_id":4,
"key_name":"body"},
{"parent_id":2,"cat_name":"Bracelets","category_id":5,
"key_name":""},
{"parent_id":2,
"cat_name":"Charms","category_id":6,
"key_name":""},
{"parent_id":2,"cat_name":"Necklaces","category_id":7,
"key_name":""},
{"parent_id":2,"cat_name":"Ornamental","category_id":8,
"key_name":""},
{"parent_id":2,
"cat_name":"Rings & Studs","category_id":9,
"key_name":""},
{"parent_id":2,
"cat_name":"Jewelry Metal","category_id":10,"key_name":""},{"parent_id":2,
"cat_name":"Yellow Gold","category_id":11,
"key_name":""},
{"parent_id":2,
"cat_name":"White Gold","category_id":12,"key_name":"whitegold"},{"parent_id":2,
"cat_name":"Silver","category_id":13,"key_name":"silver"}
]
// below values will be displayed in Select Metal dd
catMetalValue = [
{"parent_id":14,"cat_name":"White Gold","category_id":24,"key_name":"whitegold"},
{"parent_id":14,"cat_name":"Yellow Gold","category_id":24,"key_name":"whitegold"},
]
// below values will be displayed in Select Gems dd
catGemsValue = [
{"parent_id":15,"cat_name":"Blue Gems","category_id":25,"key_name":"bluegems"}
]
constructor(private formBuilder: FormBuilder) {
this.uploadArtWorkForm = this.formBuilder.group({
cat_id: new FormControl('', Validators.required),
categoryArray: this.formBuilder.array([]),
});
}
ngOnInit() {}
onChangeType(value, id){
console.log(value)
// solution to https://stackoverflow.com/questions/61315779/angular-8-not-getting-selected-dropdown-values-in-component-using-reactive-form?noredirect=1&lq=1
}
onChangeCategory(event, id) {
if (id) {
this.types = [
{"parent_id":1,
"cat_name":"Type",
"category_id":2,
"key_name":"type"},
{"parent_id":1,
"cat_name":"Metal",
"category_id":14,
"key_name":"metal"},
{"parent_id":1,
"cat_name":"Gems",
"category_id":15,
"key_name":"gems"}];
if(this.uploadArtWorkForm.controls['categoryArray'].length > 0){
this.uploadArtWorkForm.controls['categoryArray'].controls.length = 0
}
this.addInNewCategory(this.types);
} else {
this.types = null;
this.subTypes = null;
}
}
get category(): FormArray {
return <FormArray>this.uploadArtWorkForm.controls['categoryArray'];
}
addInNewCategory(types) {['categoryArray'];
types.forEach((element, i) => {
this.category.push(this.formBuilder.group({[element["key_name"]]: new FormControl(element["key_name"])
}));
});
}
}
推荐阅读
- css - 混合使用@supports 和@media 查询
- python - 在 Python 字典中访问 Unicode 值
- c++ - c++ 类设计、基类继承或外观设计模式
- java - 如何使程序允许在命令行上输入以空格分隔的整数列表(JAVA)
- amazon-web-services - 修改 LB 侦听器规则时出错:ValidationError:最多可以指定“2”个条件状态码:400,请求 ID
- javascript - 我们如何在 XMLHttpRequest 的回调中使用 this.responseText,即使它没有在函数中定义?
- python - ImportError:无法导入名称 MainClass
- php - 用于匹配特定标签之间特定字符串的所有实例的正则表达式
- .net - 滚动文本框
- google-custom-search - 为单页谷歌自定义搜索显示多个结果