Angular:在(更改)事件上添加动态生成的输入字段数据的问题

时间:2019-07-05 04:34:53

标签: angular typescript angular-reactive-forms angular-forms angular-in-memory-web-api

我具有一项功能,需要在单击按钮时发送动态生成的输入字段。

为了更好的理解,我在stackblitz上重新创建了该问题。

在该应用中,当我输入resourceQuantity时,resourceId字段是动态生成的。 我的问题是单独识别这些字段,然后单击一下按钮即可将其发送到服务器端。

我在stackblitz上发现的

This解决方案与之类似,但是在我的问题中,我不是删除或添加按钮单击,而是(更改)事件。

这是 HTML 代码:

<androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".landing.ui.fragment.HomeFragment">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
             <include 
                android:id="@+id/custom_toolbar"
                layout="@layout/custom_toolbar"/>
    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

这是 TS 代码:

 for (PoDetails items : ordersItemList) {
    if (nextPosition == incrementPosition) {
        if (some condition){
            break;
        } else{
            if (some condition){
                continue;
            } else{
                //I want to restart the for-each loop here
            }
         }
    } else {
        nextPosition++;
    }
 }

请让我知道解决我的问题的最佳方法。谢谢。

4 个答案:

答案 0 :(得分:1)

这里提供的是formArray的完美用例……唯一的区别是您需要根据在resourceQuantity字段中输入的值添加formControls。

相关的 HTML

<mat-card>
    <form [formGroup]="form" (submit)="add()">
        <mat-form-field>
            <input matInput type="number" formControlName="employeeId" placeholder="Enter Employee Id" (change)='updateFormString()'/>
      </mat-form-field><br/><br/>
      <mat-form-field>
            <input matInput formControlName="employeeName" placeholder="Enter Employee Name" (change)='updateFormString()'/>
      </mat-form-field><br/><br/>
      <mat-form-field>
            <input  matInput type="number" formControlName="resourceQuantity" [(ngModel)]="resourceQuantity" placeholder="Enter Resource Quantity" (change)="somethingChanged()"/> 
        </mat-form-field><br/><br/>
           <!--
             <div>
                <ul>
                    <li *ngFor="let item of counter(resourceQuantity)">
                        <input  matInput type="number" placeholder="Enter Resource Number" formControlName="resourceId"/> 
                    </li>       
                </ul>
            </div>
            -->
        <div fxLayout>
            <div>
                <button
                    mat-raised-button
                    color="accent" [disabled] = "form.invalid">Save
                </button>
            </div>
        </div>

        <div formArrayName='resourceId'>
          <br/>
          <div *ngFor='let item of resourceId.controls; let i = index'>
            <input type='text' [formControlName]="i" >
          </div>
        </div>

    </form>
</mat-card>

{{formString}}

相关的 TS

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray, FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  form: FormGroup;
  resourceQuantity: any;
  formString: string;

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.form = this.fb.group({
      'employeeId': new FormControl(null, { validators: [Validators.required] }),
      'employeeName': new FormControl(null, { validators: [Validators.required] }),
      'resourceQuantity': new FormControl(null, { validators: [Validators.required] }),
      //'resourceId': new FormControl(null, {validators: [Validators.required]}),
      resourceId: this.fb.array([
        this.fb.control('test entry default')
      ])
    });
  }

  updateFormString() {
    this.formString = JSON.stringify(this.form.value);
  }

  somethingChanged() {
    for (var i = 1; i < this.resourceQuantity; i++) {
      this.addResource();
    }
    this.updateFormString();
  }

  get resourceId() {
    return this.form.get('resourceId') as FormArray;
  }

  addResource() {
    this.resourceId.push(this.fb.control('test entry additional'));
  }

  counter(i: number) {
    return new Array(i);
  }
}

工作stackblitz available here

答案 1 :(得分:1)

您应使用FormArray解决此问题。 StackBlitz Demo

1。按照以下步骤将resourceIdFormControl更改为FormArray

 'resourceId': new FormArray([])

2。根据资源数量,更改您的counter方法以将FormControl推入FormArray中,此方法在更改事件触发时调用资源数量。它从resourceQuantity获取FormGroup的值,然后清除FormArray的值。之后,它将遍历索引以动态创建FormControl并将其推入FormArray

counter() {
    const index = parseInt(this.form.value.resourceQuantity);
    (this.form.controls.resourceId as FormArray).clear();
    for(let i = 0; i < index; i++) {
      const formControl = new FormControl();
      (this.form.controls.resourceId as FormArray).push(formControl);
    }
}

3。使用吸气剂轻松访问控件

  get formControls(): any {
    return this.form.controls;
  }

  get resourceIDControls(): any {
    return this.form.controls.resourceId['controls'];
  }

4。更改HTML以遍历FormArray并动态设置FormControlName

<div formArrayName="resourceId">
     <ul>
         <li *ngFor="let item of resourceIDControls; let i = index">
             <input  matInput type="number" placeholder="Enter Resource Number" [formControlName]="i"/> 
         </li>       
     </ul>
 </div>

Sample Inputs - Demo

Form Value after the submission will look like this

答案 2 :(得分:1)

避免同时使用Private Function Datos() As Integer Dim id As Integer Dim name As String = "" Dim ExistText = "" Using cnn As New OleDbConnection("Your connection string") Using cmd As New OleDbCommand("SELECT Id, ddi, Name FROM Usuario WHERE ddi= @ddi;", cnn) cmd.Parameters.Add("@ddi", OleDbType.Integer).Value = CInt(Txddi.Text) cnn.Open() Using search As OleDbDataReader = cmd.ExecuteReader If search.Read Then id = CInt(search("Id")) name = search("Name").ToString ExistText = "Exist" Else ExistText = "New" End If End Using 'closes and disposes reader End Using 'closes and disposes command End Using 'closes and disposes connection LblName.Text = name LblExist.Text = ExistText Return id End Function ngModel。您可以在组件中使用formControl和getter函数来获得结果。

编辑:我已经通过在formArray valueChanges上订阅resourceQuantity并生成{{1} }检测到更改时。这样可以实时创建资源。

编辑:请不要忘记从formControlunsubscribe,以防止内存泄漏。我更新了我的Stackblitz来显示相同​​的内容。

这是StackBlitz

上的有效示例

答案 3 :(得分:1)

我还将设置我的员工模型以包括一个Resource数组;

import { Resource } from './resource.model';

export interface Employee {
    employeeId: number;
    employeeName: string;
    resourceQuantity: number;
    resourceIds: Resource[];
}

然后您的资源只需要一个ID:

export interface Resource {
    resourceId: number;
}