2

我正在尝试获取一组表单字段来验证或更新我的父表单组。有人可以告诉我我做错了什么吗?

我基本上想要实现的是添加一个具有多个表单字段的新“供应商行”。并验证每个字段。目前只有 formGroup 的外部字段正在验证。我也不想验证每个 formArray 字段。如果有帮助,我正在使用 Ant 的 ng-zorro 框架。提前致谢。

这是代码:

新项目.component.html

<div nz-row nzGutter="16">
  <div nz-col>
    <h2>Create new Project</h2>
  </div>
</div>
<div nz-row nzGutter="16">
  <div nz-col nzSpan="6" nzOffset="18">
    <button nz-button nzType="primary" nzBlock>
      <i nz-icon nzType="download"></i>Primary
    </button>
  </div>
</div>
<form nz-form nzLayout="vertical" [formGroup]="validateForm" (ngSubmit)="submitForm()">
  <div nz-row nzGutter="16">
    <div nz-col nzSpan="6">
      <nz-form-item>
        <nz-form-label>Project Name</nz-form-label>
        <nz-form-control nzErrorTip="Please enter a project name">
          <input formControlName="projectName" nz-input placeholder="Project Name" />
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col nzSpan="6">
      <nz-form-item>
        <nz-form-label>Company Code</nz-form-label>
        <nz-form-control nzErrorTip="Please select a company code" nzHasFeedback>
          <app-company-select formControlName="selectedCompanyValue"></app-company-select>
        </nz-form-control>
      </nz-form-item>
    </div>
  </div>
  <div nz-row nzGutter="16">
    <div nz-col nzSpan="5">
      Vendor
    </div>
    <div nz-col nzSpan="4">
      Budget
    </div>
    <div nz-col nzSpan="3">
      Available Budget
    </div>
    <div nz-col nzSpan="4">
      Budget to use in Project
    </div>
    <div nz-col nzSpan="2">
      Currency
    </div>
    <div nz-col nzSpan="2">
      Layer 1
    </div>
    <div nz-col nzSpan="2">
      Layer 2
    </div>
    <div nz-col nzSpan="2">
      Layer 3
    </div>
  </div>
  <div formArrayName="projectHeaders">
    <ng-container *ngFor="let projectHeader of validateForm.get('projectHeaders').controls; let i = index" formGroupName="{{i}}">
      <div nz-row nzGutter="16">
        <div nz-col nzSpan="5">
          <nz-form-item>
            <nz-form-control nzErrorTip="Please select a vendor" nzHasFeedback>
              <app-vendor-search formControlName="selectedVendorValue"></app-vendor-search>
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="4">
          <nz-form-item>
            <nz-form-control nzErrorTip="Please select a budget" nzHasFeedback>
              <nz-select formControlName="selectedBudgetValue" nzAllowClear nzPlaceHolder="Budgets">
                <nz-option *ngFor="let o of listOfBudgets" [nzLabel]="o.text" [nzValue]="o.value"> </nz-option>
              </nz-select>
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="3">
          <nz-form-item>
            <nz-form-control>
              <input nz-input placeholder="" formControlName="availableBudget" [disabled]="true" />
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="4">
          <nz-form-item>
            <nz-form-control nzErrorTip="Make sure you have selected a valid budget amount.">
              <nz-input-number formControlName="budgetToUseInProject" [nzFormatter]="parseCurrencyEUR" style="width: 100%;">
              </nz-input-number>
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="2">
          <nz-form-item>
            <nz-form-control>
              <input nz-input placeholder="" formControlName="currency" [disabled]="true" />
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="2">
          <nz-form-item>
            <nz-form-control nzErrorTip="Please select a layer" nzHasFeedback>
              <nz-select formControlName="layer1" nzAllowClear nzPlaceHolder="Layer 1">
                <nz-option *ngFor="let o of layerOneOptions" [nzLabel]="o.text" [nzValue]="o.value"> </nz-option>
              </nz-select>
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="2">
          <nz-form-item>
            <nz-form-control nzErrorTip="Please select a layer" nzHasFeedback>
              <nz-select formControlName="layer2" nzAllowClear nzPlaceHolder="Layer 2">
                <nz-option *ngFor="let o of layerOneTwoOptions" [nzLabel]="o.text" [nzValue]="o.value"> </nz-option>
              </nz-select>
            </nz-form-control>
          </nz-form-item>
        </div>
        <div nz-col nzSpan="2">
          <nz-form-item>
            <nz-form-control nzErrorTip="Please select a layer" nzHasFeedback>
              <nz-select formControlName="layer3" nzAllowClear nzPlaceHolder="Layer 3">
                <nz-option *ngFor="let o of layerThreeOptions" [nzLabel]="o.text" [nzValue]="o.value"> </nz-option>
              </nz-select>
            </nz-form-control>
          </nz-form-item>
        </div>
      </div>
    </ng-container>
  </div>
  <!-- <div formArrayName="projectHeaders">
    <ng-container *ngFor="let projectHeader of validateForm.get('projectHeaders').controls; let i = index">
      <app-vendor-line [group]="projectHeader"></app-vendor-line>
    </ng-container>
  </div> -->
  <div nz-row nzGutter="16">
    <div nz-col nzSpan="24">
      <nz-form-item>
        <nz-form-control nzErrorTip="Please">
          <button nz-button nzSize="large" nzType="primary" nzBlock>Primary</button>
        </nz-form-control>
      </nz-form-item>
    </div>
  </div>
</form>

新项目.component.ts

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

@Component({
  selector: 'app-new-project',
  templateUrl: './new-project.component.html',
  styleUrls: ['./new-project.component.css']
})
export class NewProjectComponent implements OnInit {
  validateForm: FormGroup;

  constructor(private fb: FormBuilder) {

    this.validateForm = this.fb.group({
      selectedCompanyValue: [null, [Validators.required]],
      projectName: [null, [Validators.required]],
      projectHeaders: this.fb.array([]),
      projectLines: []
    });
  }

  ngOnInit() {


    this.addHeaderLine();
  }

  submitForm(): void {
    // tslint:disable-next-line: forin
    for (const i in this.validateForm.controls) {
      this.validateForm.controls[i].markAsDirty();
      this.validateForm.controls[i].updateValueAndValidity();
      if (i === 'projectHeaders') {
        const control = this.validateForm.get('projectHeaders') as FormArray;
        for (const j of control.controls) {
          j.markAsDirty();
          j.updateValueAndValidity();
        }
      }
    }
  }

  initProjectHeader() {
    return this.fb.group({
      selectedVendorValue: [null, Validators.compose([Validators.required])],
      selectedBudgetValue: [null, Validators.compose([Validators.required])],
      availableBudget: [{value: 0, disabled: true }, Validators.compose([Validators.required])],
      budgetToUseInProject: [0, Validators.compose([Validators.required])],
      currency: [{value: 'EUR', disabled: true}, Validators.compose([Validators.required])],
      layer1: [null, Validators.compose([Validators.required])],
      layer2: [null, Validators.compose([Validators.required])],
      layer3: [null, Validators.compose([Validators.required])]
    });
  }

  addHeaderLine() {
    const control = this.validateForm.controls.projectHeaders as FormArray;
    control.push(this.initProjectHeader());
  }

  parseCurrencyEUR(value: number): string {
    return formatNumber(value, 'de_DE');
  }


}

4

2 回答 2

2

我设法弄清楚问题所在。显然,您甚至必须将嵌套表单标记为脏并更新它们,因此我修改了 onSubmit 函数来执行此操作。感谢所有其他试图提供帮助的人:)

submitForm(): void {
  // tslint:disable-next-line: forin
  for (const i in this.validateForm.controls) {
    this.validateForm.controls[i].markAsDirty();
    this.validateForm.controls[i].updateValueAndValidity();
    if (i === 'projectHeaders') {
      const control = this.validateForm.get('projectHeaders') as FormArray;
      // tslint:disable-next-line: forin
      for (const j in control.controls) {
        const controlTwo = control.controls[j] as FormGroup;
        // tslint:disable-next-line: forin
        for (const k in controlTwo.controls) {
          controlTwo.controls[k].markAsDirty();
          controlTwo.controls[k].updateValueAndValidity();
        }
      }
    }
    if (i === 'projectLines') {
      const control = this.validateForm.get('projectLines') as FormArray;
      // tslint:disable-next-line: forin
      for (const j in control.controls) {
        const controlTwo = control.controls[j] as FormGroup;
        // tslint:disable-next-line: forin
        for (const k in controlTwo.controls) {
          controlTwo.controls[k].markAsDirty();
          controlTwo.controls[k].updateValueAndValidity();
        }
      }
    }
  }
}
于 2019-11-29T11:52:31.657 回答
1

当您使用Validators.required时,它将使表单无效或有效,如果 required 失败,该字段也将变为无效。因此,如果它满足条件,它将使表单有效,否则无效。您可以放置​​自定义验证信息或将边框设为红色并禁用提交按钮,以显示该字段是必填字段且不允许提交

在 css::input.form-control.ng-invalid { border: 2px solid red; } 你的 ts 文件很好。只需添加验证消息或将字段边框设置为红色,以防不满足要求。

于 2019-11-21T07:18:28.100 回答