首页 > 解决方案 > 使用 FormArray 动态添加 FormControl 也会提交我的表单

问题描述

单击按钮以使用 FormArray 类添加 URL 是提交整个表单,因此不会让用户在每次单击按钮时不向数据库提交新条目的情况下输入多个 URL。

在我看来,这似乎是一个事件冒泡问题,但使用 $event.stopPropagation 根本没有改变行为。

app.component.html

<div class="flex-container">
  <form [formGroup]="form" (ngSubmit)="submit()" class="card">
    <div class="form-group">
      <label for="">Title</label>
      <input 
        type="text"
        formControlName="title"
        class="form-control"
      />
    </div>
    <div class="form-group">
      <label for="">Image URLs</label>
      <input
        type="text"
        class="form-control"
        #url
      >
      <button (click)="addUrl(url, $event)">Add a URL</button>
      <ul>
        <li *ngFor="let url of imageUrls.controls" class="form-control" style="color: black;">
          {{ url.value }}
        </li>
      </ul>
    </div>
    <div class="form-group">
      <label for="">Description</label>
      <textarea
        formControlName="description"
        class="form-control"
      >
      </textarea>
    </div>
    <button class="btn btn-primary" type="submit">Submit</button>
  </form>
</div>

app.component.ts

import { Component, OnInit } from '@angular/core';
import { Subscription, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireList, AngularFireObject  } from 'angularfire2/database';
import { AngularFirestore } from '@angular/fire/firestore';
import { FormGroup, FormArray, FormControl, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { Router } from "@angular/router";

@Component({
  selector: 'app-component',
  templateUrl: './app-component.component.html',
  styleUrls: ['./app-component.component.css']
})

export class GalleryAdminComponent {

  form: FormGroup;

  constructor(fb: FormBuilder, private router: Router) {

    this.form = fb.group({
      title: [''],
      description: [''],
      imageUrls: fb.array([])
    });
  }

  get title() {
    return this.form.get('title');
  }

  get description() {
    return this.form.get('description');
  }

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

  addUrl(url: HTMLInputElement, $event) {
    $event.stopPropagation(); //doesn't work, clicking the add url button still submits the entire form
    (this.imageUrls as FormArray).push(new FormControl(url.value));
    url.value = '';
  }

  addEvent(input: any) {
    const itemsRef = this.db.list('events');
    itemsRef.push(input);
  }

  submit() {
    console.log("this.form", this.form);
    console.log("this.form.value", this.form.value);
    this.addEvent(this.form.value);
    this.router.navigate(['/gallery']);
  }

}

我想以这样一种方式使用 FormArray,即可以一次动态地添加一个 imageUrls 的 FormControl 对象。这将让用户填写表单,添加零个或多个 imageUrl 字符串,然后单击提交按钮将 form.value 对象文字发送到服务器。

标签: angular

解决方案


只需添加type一个按钮的属性。

  <button type="button" (click)="addUrl(url, $event)">Add a URL</button>

Add a URL当您单击按钮时,这不会让您的表单提交。

发生这种情况的原因:

按钮类型属性的默认值为“提交”。点击这里查看更多

所以将其设置type="button"为生成一个不提交表单的按钮。


推荐阅读