typescript 当其他字段值发生变化时,如何更新React式表单字段值

mdfafbf1  于 2023-06-24  发布在  TypeScript
关注(0)|答案(1)|浏览(137)

我有下面的React形式,我使用的形式建设者与组。
图:x1c 0d1x
下面是组件的HTML代码

<div class="">    
    <form [formGroup]="FeedBack" (ngSubmit)="onSubmit()">
        <div
            class="grid grid-cols-6 gap-x-16 py-5 px-4 text-sm text-gray-700 border-b border-gray-200 dark:border-gray-700">
            <div class="text-gray-500 dark:text-gray-400 flex">
                Number of Cases <input formControlName="caseCount" type="text" id="case-count"
                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
            </div>
            <div class="text-gray-500 dark:text-gray-400 "></div>
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div class="text-gray-500 dark:text-gray-400"></div>

            <div>
                <button type="button" (click)="addNewRow()"
                    class="text-white block w-full bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:ring-blue-200 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:focus:ring-blue-900">Add</button>
            </div>
        </div>

        <table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
            <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
                <tr>
                    <th scope="col" class="py-3 px-6">Property</th>
                    <th scope="col" class="py-3 px-6">Group</th>
                    <th scope="col" class="py-3 px-6">Variable Name</th>
                    <th scope="col" class="py-3 px-6">Min Value</th>
                    <th scope="col" class="py-3 px-6">Max Value</th>
                    <th scope="col" class="py-3 px-6"></th>
                </tr>
            </thead>
            <tbody formArrayName="Rows">
                <tr *ngFor="let obj of formArr.controls; let i = index; let l = last" [formGroupName]="i"
                    class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
                    <td class="py-4 px-6">
                        <select formControlName="property" (change)="selectPropertyChangeHandler($event)">
                            <option *ngFor="let property of propertyList; " value="{{property.id}}">
                                {{property.pname}}
                            </option>
                        </select>
                    </td>
                    <td class="py-4 px-6">
                        <select formControlName="group" (change)="selectGroupChangeHandler($event)">
                            <option *ngFor="let group of groupList; " value="{{group.id}}">
                                {{group.gname}}
                            </option>
                        </select>
                    </td>
                    <td class="py-4 px-6">
                        <input formControlName="variableName" type="text" readonly id="variable-name"
                            class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                    </td>
                    <td class="py-4 px-6">
                        <input formControlName="minValue" type="text" id="min-input"
                            class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                    </td>
                    <td class="py-4 px-6">
                        <input formControlName="maxValue" type="text" id="max-input"
                            class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                    </td>
                    <td class="py-4 px-6">
                        <button type="button" (click)="deleteRow(i)" *ngIf="FeedBack.value.Rows.length > 1">
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                                stroke="currentColor" class="w-6 h-6">
                                <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                            </svg>
                        </button>
                    </td>
                </tr>
            </tbody>
        </table>

        <div
            class="grid grid-cols-5 gap-x-16 py-5 px-4 text-sm text-gray-700 border-b border-gray-200 dark:border-gray-700">
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div class="text-gray-500 dark:text-gray-400"></div>
            <div>
                <button type="submit"
                    class="text-white block w-full bg-blue-600 hover:bg-blue-700 focus:ring-4 focus:ring-blue-200 font-medium rounded-lg text-sm px-4 py-2.5 text-center dark:focus:ring-blue-900">Submit</button>
            </div>
        </div>
        <pre>{{ FeedBack.value | json }}</pre>
    </form>
</div>

html表单的component.ts文件如下所示。

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, FormControl } from '@angular/forms';
import { HttpClient, HttpHeaders } from '@angular/common/http'

interface APIResponse {
  data: [];
  message: string;
  status: boolean;
}

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  FeedBack!: FormGroup;

  ngOnInit(): void {
    this.buildGroupList()
  }

  constructor(private http: HttpClient, private formBuilder: FormBuilder) {
    this.addDefaultRow();
  }

  addDefaultRow() {
    this.FeedBack = this.formBuilder.group({
      Rows: this.formBuilder.array([this.initRows()]),
      caseCount: new FormControl(null)
    });
  }

  initRows() {
    return this.formBuilder.group({
      property: [''],
      group: [''],
      variableName: [],
      minValue: [0],
      maxValue: [0]
    });
  }

  get formArr() {
    return this.FeedBack.get('Rows') as FormArray;
  }

  addRow(obj: any) {
    return this.formBuilder.group({
      property: [obj.property],
      group: [obj.group],
      variableName: [obj.variableName],
      minValue: [obj.minValue],
      maxValue: [obj.maxValue]
    });
  }

  addNewRow() {
    let obj1 = {
      property: '',
      group: '',
      variableName: '',
      minValue: 0,
      maxValue: 0
    };
    this.formArr.push(this.addRow(obj1));
  }

  deleteRow(index: number) {
    this.formArr.removeAt(index);
  }

  onSubmit() {
    console.log('Your form data : ', this.FeedBack.value);
  }

  private buildGroupList() {
    this.http.get<APIResponse>("http://127.0.0.1:5000/mrg_groups").subscribe((res) => {
      let groupList: { id: string, gname: string }[] = [{ id: '', gname: 'Select Group' },]
      res['data'].forEach((group) => {
        groupList.push({ id: group, gname: group })
      });
      this.groupList = groupList
      console.log(this.groupList)
    })
  }

  groupList: { id: string, gname: string }[] = [];

  propertyList: { id: string, pname: string }[] = [
    { id: '', pname: 'Select Property' },
    { id: 'AAA', pname: 'PROP A3' },
    { id: 'BBB', pname: 'PROP B3' },
    { id: 'CCC', pname: 'PROP C3' },
    { id: 'DDD', pname: 'PROP D3' },
    { id: 'EEE', pname: 'PROP E3' }
  ];

  selectedProperty: string = '';
  selectPropertyChangeHandler(event: any) {
    this.selectedProperty = event.target.value;
    console.log('this.selectedProperty: ', this.selectedProperty)
  }

  selectedGroup: string = '';
  selectGroupChangeHandler(event: any) {
    this.selectedGroup = event.target.value;
    console.log('this.selectedGroup: ', this.selectedGroup)
  }
}

我面临的挑战是我的“VARIABLENAME”列值是属性字段和组字段的连接。因此,每当用户选择这两个下拉菜单时,“VARIABLE NAME”字段应该自动更新为更新后的值,如“AAA_S01P”(第一行)。
下面是事件监听函数的下拉按钮,我试图这样做。

selectedProperty: string = '';
  selectPropertyChangeHandler(event: any) {
    this.selectedProperty = event.target.value;
    console.log('this.selectedProperty: ', this.selectedProperty)
  }

  selectedGroup: string = '';
  selectGroupChangeHandler(event: any) {
    this.selectedGroup = event.target.value;
    console.log('this.selectedGroup: ', this.selectedGroup)
  }

我尝试了几种技术,比如“setValue/updateValue/patchValue”来做到这一点。但是,什么都不起作用。也许我做错了什么地方。需要一些指导。

yi0zb3m4

yi0zb3m41#

由于您的variableNameFormControlFormArrayFormGroup的控件,因此要执行setValue/updateValue/patchValue方法中的任何一个,您必须记住提供行索引以确定应使用哪个FormGroup
在我看来:
1.当您使用Reactive形式时,传递event(用于选定值),以便selectPropertyChangeHandlerselectGroupChangeHandler方法可以被替换。您可以通过使用rowIndex指定FormControl来获取这些值。

  1. selectPropertyChangeHandlerselectGroupChangeHandler可以合并为一个(我命名为selectPropertyOrGroupChangeHandler)。
selectPropertyOrGroupChangeHandler(rowIndex: number) {
  let formGroup = this.formArr.controls[rowIndex] as FormGroup;
  let property = formGroup.controls['property'].value;
  let group = formGroup.controls['group'].value;

  if (property && group)
    formGroup.controls['variableName'].patchValue(`${property}_${group}`);
}

并应用视图中的方法:

<select
  formControlName="property"
  (change)="selectPropertyOrGroupChangeHandler(i)"
>
  ...
</select>

<select
  formControlName="group"
  (change)="selectPropertyOrGroupChangeHandler(i)"
>
  ...
</select>

Demo @ StackBlitz

相关问题