具有多个表单组的Angular 6动态表单

时间:2019-01-18 15:47:31

标签: angular angular2-forms

我正在使用Angular 6构建动态表单。请在此处找到https://stackblitz.com/edit/angular6-dynamic-form-ovyftx

但是在提交时没有获得正确格式的表单值。我越来越喜欢

{"group1":{"brave":"","firstName":"Bombasto","emailAddress":"","multiBox":""},"group2":{"brave":"","firstName":"Bombasto","emailAddress":"","multiBox":""}}

我应该像

{"group1":{"brave":"","firstName":"Bombasto"},"group2":{"emailAddress":"","multiBox":""}}

因为字段属于不同的组。如何解决这个问题?另外,我怎样才能在小组的基础上验证表格。例如,如果一个字段无效,则该组应显示红色边框。

2 个答案:

答案 0 :(得分:1)

您在服务问题control.service上犯了一个小错误。您要将新控件添加到相同的变量“ group”中。因此在第二个循环中,您之前的控件也已添加到其中。只需在下一个循环中重置其值即可。您最好解决第一个问题。

Object.keys(questions).forEach((eachgroup: string) => {
    group = {}; //here you new to reset the value of group
    questions[eachgroup].forEach(question => {
      group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
        : new FormControl(question.value || '');
    });
    sections[eachgroup] = new FormGroup(group);
  });

对于验证部分,您可以使用[ngClass]指令并将自定义的CSS应用于无效输入,如下所示:

    <div [formGroup]="form" [ngClass]="{'isa_error':isValid?false:true}">
        <label [attr.for]="question.key">{{question.label}}</label>
....
</div>

工作代码示例:https://stackblitz.com/edit/angular6-dynamic-form-wvspuw

应用:https://angular6-dynamic-form-wvspuw.stackblitz.io

答案 1 :(得分:0)

请查看此stackblitz-angular-formgroup-as-array。 formArray的简化示例。

所以在我的示例中,它将是:

form: FormGroup = this.fb.group({
  tops: this.fb.array([])
}, {
  validator: this.exampleValidator
});

exampleValidator(e) {
  //does logic for validity on form
  console.log(e);
}
export class SelectMultipleExample implements OnInit {


  form: FormGroup = this.fb.group({
    tops: this.fb.array([])
  });

  toppingList = [{
      id: 0,
      name: 'Extra cheese'
    },
    {
      id: 0,
      name: 'Mushroom'
    },
    {
      id: 0,
      name: 'Onion'
    },
    {
      id: 0,
      name: 'Pepperoni'
    },
    {
      id: 0,
      name: 'Sausage'
    },
    {
      id: 0,
      name: 'Tomato'
    }
  ];

  complexOrderToppings = [{
      order: {
        selected: [{
            id: 0,
            name: "Extra cheese"
          },
          {
            id: 0,
            name: "Mushroom"
          },
          {
            id: 0,
            name: "Onion"
          },
          {
            id: 0,
            name: "Pepperoni"
          }
        ]
      }
    },
    {
      order: {
        selected: [{
            id: 0,
            name: "Extra cheese"
          },
          {
            id: 0,
            name: "Mushroom"
          },
          {
            id: 0,
            name: "Onion"
          },
          {
            id: 0,
            name: "Pepperoni"
          }
        ]
      }
    },
    {
      order: {
        selected: [{
            id: 0,
            name: "Extra cheese"
          },
          {
            id: 0,
            name: "Mushroom"
          },
          {
            id: 0,
            name: "Onion"
          },
          {
            id: 0,
            name: "Pepperoni"
          }
        ]
      }
    }
  ];

  simpleOrderToppings = [{
      order: [{
          id: 0,
          name: "Extra cheese"
        },
        {
          id: 0,
          name: "Mushroom"
        },
        {
          id: 0,
          name: "Onion"
        },
        {
          id: 0,
          name: "Pepperoni"
        }
      ]
    },
    {
      order: [{
          id: 0,
          name: "Extra cheese"
        },
        {
          id: 0,
          name: "Mushroom"
        },
        {
          id: 0,
          name: "Onion"
        },
        {
          id: 0,
          name: "Pepperoni"
        }
      ]
    },
    {
      order: [{
          id: 0,
          name: "Extra cheese"
        },
        {
          id: 0,
          name: "Mushroom"
        },
        {
          id: 0,
          name: "Onion"
        },
        {
          id: 0,
          name: "Pepperoni"
        }
      ]
    }
  ];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.setToppings(this.complexOrderToppings);
  }

  get getTops(): FormArray {
    return this.form.get('tops') as FormArray;
  }

  setToppings(toppings: any) {
    const toppingsFGs = toppings.map(topping => this.fb.group(topping));
    const topppingFormArray = this.fb.array(toppingsFGs);
    this.form.setControl('tops', topppingFormArray);
    this.setTopsNewValue();
  }

  compareSelected(o1: any, o2: any): boolean {
    if (!o1 || !o2) {
      return false;
    }
    const isSelected = o1.name === o2.name && o1.id === o2.id;
    return isSelected;
  }

  setTopsNewValue() {
    const tops = this.getTops;
    tops.controls.map(t => {
      const newValue = t.value.order.selected;
      t.setValue({
        order: newValue
      });
    });
  }
}


/**  Copyright 2018 Google Inc. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license */
<form [formGroup]="form">
  <div formArrayName="tops">
    <div *ngFor="let top of getTops.controls; let i=index" [formGroupName]="i">
      <mat-form-field>
        <mat-select [placeholder]="'Selected Toppings ' + (i + 1)" formControlName="order" multiple [compareWith]="compareSelected">
          <mat-option *ngFor="let topping of toppingList" [value]="topping">
            {{topping.name}}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </div>
  </div>
</form>

<pre>{{form.value | json}}</pre>