Angular 8:基于组件在html中动态设置formControlName [英] Angular 8: Dynamically set formControlName in html based on component

查看:40
本文介绍了Angular 8:基于组件在html中动态设置formControlName的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 db 表中,我有key_name",它在 API 中成功返回并且运行良好.

我想要做的是在 html 和组件中将这些字段值设置为 formControlName 我使用的是反应式表单,所以我尝试了 formArrayName.

基于更改事件,我在 categoryArray 中推送新的 formControl 并将其键分配为 db 字段的值.

这是我的HTML:

<div formArrayName="categoryArray" *ngFor="let type of types; let k = index"><div [formGroupName]="k"><div class="form-group"><label>选择{{ type.cat_name }}</label><select class="form-control custom-select"(change)="onChangeType($event.target.value)"formControlName="{{ type.key_name }}" ><option value="">-- 选择--</option><option *ngFor="let type of types" [value]="type.category_id">{{type.cat_name}}</选项></选择>

component.ts:

onChangeCategory(id) {如果(ID){this.artistService.fetchTypeAndSubTypes(id).subscribe(res => {如果(res.status == 200){this.types = res.datathis.addInNewCategory(this.types)}})} 别的 {this.types = nullthis.subTypes = null}}获取类别():FormArray {return this.uploadArtWorkForm.controls.categoryArray;}addInNewCategory(类型){让 obj = {}types.forEach(元素 => {obj[element['key_name']] = [null, [Validators.required]]});console.log("obj", obj)this.category.push(this.formBuilder.group(obj));}

我想要存档的是,基于第 1 个类别选择,所有第 2 个级别的类别将显示为动态 HTML 下拉列表,其子类别列表在下拉列表中.

我遇到的错误:

ERROR 错误:找不到带有路径的控件:'categoryArray ->1'ERROR 错误:找不到路径控制:'categoryArray ->1 ->金属'

设置表单控件名称后,如何设置每个新创建的下拉列表的值?我需要从数据库中获取它.

这里是 Stackblitz:https://stackblitz.com/edit/dyncamic-populating-dropdown

提前致谢

解决方案

尝试自己修改代码,至少修复了以下错误:

错误错误:找不到路径控制:'categoryArray -> 1'

错误错误:找不到路径控制:'categoryArray -> 1 -> metal'

但是您仍然需要使用我的解决方案进行改进.

<块引用>

修改你的 app.component.html 如下:

<form [formGroup]="uploadArtWorkForm" (ngSubmit)="addUploadArtWorkForm();"><div class="col-md-6"><div class="form-group"><label>选择类别:</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="">-- 选择--</option><option *ngFor="let category of parentCategories" [value] ="category.category_id">{{category.cat_name}}</选项></选择><div class="invalid-feedback" *ngIf="uploadArtWorkForm.controls['cat_id'].errors"><div *ngIf="uploadArtWorkForm.controls['cat_id'].errors.required">类别是</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>选择{{ 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="">-- 选择--</option><option *ngFor="let type of catTypeValue" [value]="type.category_id">{{type.cat_name}}</选项></选择><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="">-- 选择--</option><option *ngFor="let type of catMetalValue" [value]="type.category_id">{{type.cat_name}}</选项></选择><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="">-- 选择--</option><option *ngFor="let type of catGemsValue" [value]="type.category_id">{{type.cat_name}}</选项></选择>

</表单>

<块引用>

和 app.component.ts 如下:

import { Component } from "@angular/core";从@angular/forms"导入 { FormGroup, FormBuilder, Validators, FormArray, FormControl };@成分({选择器:我的应用程序",templateUrl: "./app.component.html",styleUrls: ["./app.component.css"]})导出类 AppComponent {上传艺术作品表格:任何;上传ArtWorkForm1:任何;isFormSubmitted: boolean = false;父类别 = [{"parent_id":0,"cat_name":"珠宝","category_id":1},{"parent_id":0,"cat_name":"绘画","category_id":16},{"parent_id":0,"cat_name":"照片","category_id":22}];类型;子类型;//下面的值将显示在选择类型下拉列表中猫类型值 = [{"parent_id":2,"cat_name":"脚链","category_id":3,"key_name":"脚链"},{parent_id":2,"cat_name":"身体","category_id":4,"key_name":"body"},{"parent_id":2,"cat_name":"手链","category_id":5,"key_name":""},{parent_id":2,"cat_name":"魅力","category_id":6,"key_name":""},{"parent_id":2,"cat_name":"项链","category_id":7,"key_name":""},{"parent_id":2,"cat_name":"观赏","category_id":8,"key_name":""},{parent_id":2,"cat_name":"戒指和耳钉","category_id":9,"key_name":""},{parent_id":2,"cat_name":"Jewelry Metal","category_id":10,"key_name":""},{"parent_id":2,"cat_name":"黄金","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"}]//下面的值将显示在 Select Metal dd 中猫金属值 = [{"parent_id":14,"cat_name":"Whitegold","category_id":24,"key_name":"whitegold"},{"parent_id":14,"cat_name":"Yellow Gold","category_id":24,"key_name":"whitegold"},]//下面的值将显示在 Select Gems dd 中catGemsValue = [{"parent_id":15,"cat_name":"Blue Gems","category_id":25,"key_name":"bluegems"}]构造函数(私有表单构建器:FormBuilder){this.uploadArtWorkForm = this.formBuilder.group({cat_id: new FormControl('', Validators.required),categoryArray: this.formBuilder.array([]),});}ngOnInit() {}onChangeType(值,ID){控制台日志(值)//https://stackoverflow.com/questions/61315779/angular-8-not-getting-selected-dropdown-values-in-component-using-reactive-form?noredirect=1&lq=1的解决方案}onChangeCategory(事件,ID){如果(ID){this.types = [{parent_id":1,"cat_name":"类型","category_id":2,"key_name":"type"},{parent_id":1,"cat_name":"金属","category_id":14,"key_name":"金属"},{parent_id":1,"cat_name":"宝石","category_id":15,"key_name":"宝石"}];if(this.uploadArtWorkForm.controls['categoryArray'].length > 0){this.uploadArtWorkForm.controls['categoryArray'].controls.length = 0}this.addInNewCategory(this.types);} 别的 {this.types = null;this.subTypes = null;}}获取类别():FormArray {return 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"])}));});}}

In db table, I have "key_name" which is successfully returning in API and working great.

What I want to do is to set those fields value as a formControlName in html and in component I am using the reactive form so I have tried formArrayName.

Based on the change event I am pushing new formControl in categoryArray and assigning its key as db field's value.

here is my 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>

component.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)   
    );

  }

What I want to archive is that based on 1st category selection all 2nd level category will be shown as a dynamic HTML dropdown who has their child category listing in the dropdown.

Errors that I am getting:

ERROR Error: Cannot find control with path: 'categoryArray -> 1'

ERROR Error: Cannot find control with path: 'categoryArray -> 1 -> metal'

EDIT: After setting up form control name, How can I set each newly created dropdown's value ? I need to fetch it from the db.

Here is Stackblitz: https://stackblitz.com/edit/dyncamic-populating-dropdown

Thanks in advance

解决方案

Tried modifying your code myself at least the errors below are fixed:

ERROR Error: Cannot find control with path: 'categoryArray -> 1'

ERROR Error: Cannot find control with path: 'categoryArray -> 1 -> metal'

But you still need to improve on your end using my solution.

Modify your app.component.html as below:

<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>

and app.component.ts as below:

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"])
      }));
    });
  }
}

这篇关于Angular 8:基于组件在html中动态设置formControlName的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆