繁体   English   中英

Angular 2:迭代反应式表单控件

[英]Angular 2: Iterate over reactive form controls

我想将markAsDirty所有控件FormGroupFormGroup

发现Object.keys可以处理这个..

    Object.keys(this.form.controls).forEach(key => {
      this.form.get(key).markAsDirty();
    });

对于 Angular 8+,请使用以下内容(基于 Michelangelo 的回答):

    Object.keys(this.form.controls).forEach(key => {
      this.form.controls[key].markAsDirty();
    });

对于它的价值,还有另一种方法可以做到这一点而不必使用Object.keys(...)魔法:

for (const field in this.form.controls) { // 'field' is a string

  const control = this.form.get(field); // 'control' is a FormControl  

}

接受的答案对于平面结构是正确的,但并不能完全回答原始问题。 一个网页可能需要嵌套的 FormGroups 和 FormArrays,我们必须考虑到这一点以创建一个强大的解决方案。

public markControlsDirty(group: FormGroup | FormArray): void {
    Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];

        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
            this.markControlsDirty(abstractControl);
        } else {
            abstractControl.markAsDirty();
        }
    });
}

似乎get函数不再用于在 Angular 8 中检索表单中的特定值,所以这就是我根据@Liviu Ilea 的答案解决它的方法。

for (const field in this.myForm.controls) { // 'field' is a string
  console.log(this.myForm.controls[field].value);
}

使用@Marcos 回答我创建了一个函数,可以调用它传递一个 formGroup 作为参数,它将每个 formGroup 子控件标记为脏,例如,只是为了使其可从代码周围的更多地方使用,将其放入服务中。

public touchAllFormFields(formGroup: FormGroup): void {
    Object.keys(formGroup.controls).forEach((key) => {
        formGroup.get(key).markAsDirty();
    });
}

希望能帮助到你 ;)

 Object.keys( this.registerForm.controls).forEach(key => { this.registerForm.controls[key].markAsDirty(); });

这对我有用

private markFormGroupTouched(formGroup: FormGroup) {
  Object.keys(formGroup.controls).forEach((key) => {
    const control = formGroup.controls[key];
    control.markAsDirty();
    if ((control instanceof FormGroup)) {
      this.markFormGroupTouched(control);
    }
  });
}

我创建了这个函数来使它*我有一个名为“order”的控件,并将索引传递给他。

{"conditionGroups": [
   {
     "order": null,
     "conditions": []
   }
  ]
}


updateFormData() {
    const control = <FormArray>this.form.controls['conditionGroups'];  
    control.value.map((x,index)=>{
    x.order = index; 
 })

基于@Keenan Diggs 的回答,我编写了一个通用函数来遍历平面或嵌套表单,它接受对每个表单控件执行的操作:

export function traverseForm(
    form: FormGroup | FormArray, 
    fn: ((c: AbstractControl, name: string, path: string) => void),
    initialPath: string = '') {
  Object.keys(form.controls).forEach((key: string) => {
    const abstractControl = form.controls[key];
    const path = initialPath ? (initialPath + '.' + key) : key;
    fn(abstractControl, key, path);
    if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
        traverseForm(abstractControl, fn, path);
    }
  });
} 

像这样使用:

const markAsDirty = (ctrl: AbstractControl) => {
   if (!(abstractControl instanceof FormGroup) && !(abstractControl instanceof FormArray)) {
      abstractControl.markAsDirty();
   }
}
traverseForm(form, markAsDirty);

这是我对您的问题的解决方案,我正在使用带有索引的 for 循环,希望这会有所帮助。

    for (const key of Object.keys(this.forms.controls)) {
      this.forms.controls[key].markAsDirty();
    }

我正在为具有多个文件上传表单的项目寻找类似的解决方案。 我需要创建一个表单数据对象并在多个页面中复制表单的所有字段。 这适用于 Angular 11。

const formData : FormData = new FormData();

 Object.keys(this.staffForm.controls).forEach(key => {
      console.log("Control Key => "+key); 
      console.log("Control Val => "+this.staffForm.controls[key].value); 
      formData.append(key, this.staffForm.controls[key].value);
    });

如果你不想循环你的表单控件,你也可以使用这种方式......

export class NewComponent implements OnInit {
  @ViewChild(ClrForm) clrForm: ClrForm;

  form: FormGroup;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.buildForm();
  }

  onFormSubmit() {
    if (this.form.invalid) {
      this.clrForm.markAsDirty();
      return;
    }
  }

  private buildForm() {
    this.form = this.formBuilder.group({
      sender: [null, [Validators.required]],
      sentAt: ['', [Validators.required]]
    });
  }
}
<form clrForm [formGroup]="form" (submit)="onFormSubmit()">
  <div class="clr-form-control clr-row">
    <label for="sender" class="clr-control-label clr-col-4">Sender</label>
    <div class="clr-control-container clr-col-8">
      <app-custom-form-control formControlName="sender"></app-custom-form-control>
    </div>
  </div>

  <clr-date-container>
    <label class="clr-col-4">Data wysłania</label>
    <input
      type="date"
      class="clr-col-8"
      clrDate
      formControlName="sentAt"
    />
  </clr-date-container>

  <input type="submit" value="Save" />
</form>

您可以使用 formGroup 的 '_forEachChild() 方法遍历 FormGroup 的子级。 这对我在嵌套的 formGroups 中修补值有用

    this.myForm.myFormGroup._forEachChild( control => {
      control.markAsDirty();
    })    
```


迭代formGroup控件以获取每个表单控件的值的简单解决方案:


formGroup: FormGroup;

this.formGroup = this.formBuilder.group({
      control1: new FormControl('value1'),
      control2: new FormControl(`value2`),
      control3: new FormControl('value3')
    });

Object.keys(this.formGroup.controls).forEach(key => {
      console.log(this.formGroup.controls[key].value)
});

// 输出:

值1

值2

值4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM