programing

각도 2: 반응형 폼 컨트롤을 반복합니다.

starjava 2023. 5. 27. 09:16
반응형

각도 2: 반응형 폼 컨트롤을 반복합니다.

난 그러고 싶다.markAsDirty내부의 모든 제어 장치FormGroup.

알게 된 사실은Object.keys이 일을 처리할 수 있습니다.

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

Angular 8+의 경우 다음을 사용합니다(Michelango 답변 기준).

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

인것 같습니다getAngular 8에서 당신의 양식에서 특정 값을 검색하는 기능이 더 이상 작동하지 않습니다. 그래서 저는 @Liviu Ilea의 답변을 바탕으로 이렇게 해결했습니다.

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

@Marcos answer를 사용하여 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);
    }
  });
}

여기, 당신의 문제에 대한 저의 해결책이 있나요, 저는 색인이 있는 루프에 사용하고 있습니다, 이것이 도움이 되기를 바랍니다.

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

저는 이 함수를 만들기 위해 * '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);

양식 제어를 반복하지 않으려면 이 방법을 사용할 수도 있습니다.

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

언급URL : https://stackoverflow.com/questions/42235156/angular-2-iterate-over-reactive-form-controls

반응형