Angular 2:迭代反应式表单控件并标记为脏

问题描述 投票:0回答:16

我想要

markAsDirty
FormGroup
内的所有控件。

angular
16个回答
286
投票

发现

Object.keys
可以处理这个..

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

对于 Angular 8+,请使用以下内容(基于米开朗基罗的答案):

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

101
投票

无论如何,还有另一种方法可以做到这一点,而无需使用 Object.keys(...) 魔法:

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

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

}

64
投票

接受的答案对于平面形式结构来说是正确的,但没有完全回答原始问题。网页可能需要嵌套的 FormGroup 和 FormArray,我们必须考虑到这一点才能创建强大的解决方案。

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();
        }
    });
}

12
投票

似乎

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

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

8
投票

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

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

希望有帮助;)


6
投票

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


5
投票

这对我有用

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

4
投票

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

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

3
投票

我正在为具有多个文件上传表单的项目寻找类似的解决方案。我需要创建一个表单数据对象并复制多个页面中表单的所有字段。这对于 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);
    });

2
投票

迭代

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


2
投票

对我有用的是以下内容:

Object.values(this.myFormGroup.controls).forEach((myFormControl: FormControl) => {
    myFormControl.markAsDirty();
});

不确定为什么每个人都使用 Object.keys() - .values 更直接。


1
投票

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

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


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

1
投票

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

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);

0
投票

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

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>

0
投票

您可以使用 formGroup 的

_forEachChild()
方法循环遍历 FormGroup 的子级。这对我来说适用于修补嵌套 formGroups 中的值。

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

0
投票

其他答案缺少的是一种不会产生

ts-lint
typescript
任何问题的方法。

这里有一个方法。

Object.keys(this.form.controls).forEach((key) => {
  const control = this.form.get(key);
  if (control) {
    control.markAsDirty();
    //or if we wanted to change the value
    //control.setValue(value);
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.