Angular – 响应式表单数据未保存

huangapple go评论78阅读模式
英文:

Angular- Reactive Form data not getting saved

问题

在这里,

onSubmit() {
  this.productForm.markAllAsTouched(); // 标记所有表单控件为已触摸状态

  if (this.productForm.valid) {
    console.log('submit =>', this.productForm.controls['uom']['controls']);
  } else {
    alert('填写表单'); // 当字段填写不完整时触发警报
  }
}

我正在使用警报来检查数据是否已提交。我使用了this.productForm.valid函数来检查表单是否已填写完整。但是,即使字段已填写,警报仍然会触发。

您遇到的问题可能是由于表单中的动态字段导致的。当您点击“Add More”按钮并添加新字段时,这些新字段可能不会被正确地包含在this.productForm中。这可能会导致this.productForm.valid返回false,即使所有字段都已填写。

要解决此问题,您可以尝试使用Angular的FormArray来管理动态字段。在addmore函数中,您可以尝试使用FormArraypush方法来添加新的字段控件。这样,表单将包括所有已添加的字段,并且this.productForm.valid应该能够正确地检查表单是否已填写完整。

如果您需要更详细的帮助,可以提供更多关于如何添加新字段以及如何在表单中处理它们的信息。

英文:

I was working on a project with reactive forms. There I added a button 'Submit', clicking which the form was supposed to get submitted. There is also an anchor tag clicking which new fields get added. Now, if I don't add new fields and just fill-up the available fields with data and hit 'Submit' the data get submit(I check them in console.log()). But when I do 'Add More' and add new fields and fill data in the new field and then hit 'Submit', only the data from the previous data get submitted and not the new data fields.

This is the stackbltiz representation of the project

This is the HTML code

<form name="productForm" autocomplete="off" [formGroup]="productForm">
  <div
    class="col-lg-12 col-md-12 col-sm-12 col-12 col-xs-12"
    formArrayName="uom"
    *ngFor="let item of productForm.controls['uom']['controls']; let i = index"
  >
    <div
      [formGroupName]="i"
      class="row col-lg-12 col-md-12 col-sm-12 col-12 col-xs-12 mt-2 p-0"
    >
      {{ i + 1 }}
      <div class="col-lg-2 col-md-2 col-sm-2 col-2 col-xs-12">
        <select
          role="listbox"
          formControlName="type"
          placeholder="Type"
          class="select form-control"
          aria-label="Type"
        >
          <option *ngFor="let list of typeList" [value]="list.tyopeId">
            {{ list.typeName }}
          </option>
        </select>
      </div>
      <div class="col-lg-2 col-md-2 col-sm-2 col-2 col-xs-12">
        <select
          role="listbox"
          formControlName="name"
          placeholder="Name"
          class="select form-control"
          aria-label="Name"
        >
          <option *ngFor="let list of nameList" [value]="list">
            {{ list }}
          </option>
        </select>
      </div>
      <div class="col-lg-2 col-md-2 col-sm-2 col-2 col-xs-12">
        <select
          role="listbox"
          formControlName="desc"
          placeholder="Description"
          class="select form-control"
          aria-label="Description"
        >
          <option *ngFor="let list of descList" [value]="list">
            {{ list }}
          </option>
        </select>
      </div>
    </div>
    ---------------------------
  </div>
  <div style="display:flex;justify-content:space-between;">
    <div class="col-lg-12 col-md-12 col-sm-12 col-12 col-xs-12 mt-2">
      <a href="javascript:void(0)" (click)="addmore()">Add more</a>
    </div>
    <button (click)="onSubmit()">Submit</button>
  </div>
</form>

This is the ts code:

  name = 'Angular';
  productForm: FormGroup;
  typeList;
  nameList;
  descList;

  constructor(
    private formBuilder: FormBuilder,
    private readonly changeDetectorRef: ChangeDetectorRef
  ) {}

  ngOnInit() {
    this.productForm = this.formBuilder.group({
      uom: this.formBuilder.array([this.uom()]),
    });
    this.typeList = [
      {
        tyopeId: 1,
        typeName: 'Type 1',
      },
      {
        tyopeId: 1,
        typeName: 'Type 2',
      },
      {
        tyopeId: 1,
        typeName: 'Type 3',
      },
    ];

    this.nameList = ['Name 1', 'Name 2'];
    this.descList = ['Description 1', 'Description 2'];
  }

  uom() {
    return this.formBuilder.group({
      type: ['', [Validators.required]],
      name: ['', [Validators.required]],
      desc: ['', [Validators.required]],
    });
  }

  // addmore() {
  //   if (!this.productForm.invalid) {
  //     (this.productForm.controls['uom']['controls'] as FormArray).push(
  //       this.uom()
  //     );
  //   } else {
  //     alert('Fill the form');
  //   }
  // }

  addmore() {
    const uomControls = this.productForm.get('uom')['controls'] as FormGroup[];

    for (const control of uomControls) {
      control.markAllAsTouched();
    }

    if (this.productForm.valid) {
      (this.productForm.controls['uom']['controls'] as FormArray).push(
        this.uom()
      );
    } else {
      alert('Fill the form');
    }
  }

  onSubmit() {
    this.productForm.markAllAsTouched(); // Mark all form controls as touched

    if (this.productForm.valid) {
      console.log('submit =>', this.productForm.controls['uom']['controls']);
    } else {
      alert('Fill the form');
    }
  }

  ngAfterViewChecked(): void {
    this.changeDetectorRef.detectChanges();
  }

As you can see here,

  onSubmit() {
    this.productForm.markAllAsTouched(); // Mark all form controls as touched

    if (this.productForm.valid) {
      console.log('submit =>', this.productForm.controls['uom']['controls']);
    } else {
      alert('Fill the form');
    }
  }

I am using alert to check if the data is getting submitted on not. I have used this function this.productForm.valid to check if all the form is filled or not. But even when the fields are filled,the alert is still getting triggered.

答案1

得分: 1

addMore方法中,你直接将新的FormGroup推送到控件数组而不是FormArray中。

addmore() {
  ...

  if (this.productForm.valid) {
    (this.productForm.controls['uom'] as FormArray).push(...) <----
  
  ...
}

只需移除最后一个[controls],它就会按照你的预期工作。

(this.productForm.controls['uom'] as FormArray).push(...)
英文:

In the addMore method you are pushing the new FormGroup directly in the controls array instead of the FormArray.

 addmore() {
   ...

   if (this.productForm.valid) {
     (this.productForm.controls['uom']['controls'] as FormArray).push(...) <----

  ...
}

Just remove the last [controls] and it should work as you expect.

(this.productForm.controls['uom'] as FormArray).push(...)

huangapple
  • 本文由 发表于 2023年6月19日 02:50:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定