Angular 2 : 반응 형 컨트롤 반복


답변:


200

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

2
onSubmit에서이 기능을 사용할 때 오류가 발생합니다 Cannot invoke an expression whose type lacks a call signature. Type 'AbstractControl' has no compatible call signatures.. 누가 그 이유를 알고 있습니까?
maidi

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

Object.keys 또는 "for in"을 시도해도 아무것도 얻지 못합니다. 그러나 내가 console.log (form.controls)하면 객체에 포함 된 다양한 양식 컨트롤을 모두 볼 수 있습니다. 나는 당황 스럽다.
Jake Shakesworth

Angular 5를 사용하면 markAsDirty () / markAsTouched ()는 하위 FormGroups로 재귀하지 않습니다. 위의 코드를 재귀 함수로 나누고 하위 FormGroups에서 호출합니다. 사용자가 필수 요소를 터치하지 않는 경우 현재 Angular Material UI 프로젝트에서 더 잘 작동합니다. 사용자가 해당 지점에 표시하기 위해 양식을 제출하려고 할 때 호출합니다.
Robert

3
내 게시물을 읽고 자신의 답변을 업데이트 한 Thnx. 나는 모든 라인을 인쇄하여이 제한을 파악했다 있도록 공식 문서도 ... 오래된된다
미켈란젤로

57

그만한 가치를 위해, Object.keys (...) 마법 을 사용하지 않고도이 작업을 수행 할 수있는 또 다른 방법이 있습니다 .

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

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

}

루프 인덱스를 얻는 방법?
SVK

1
TSLint를 사용하는 사람들에게는 코드가 작동하지만 TSLint는 "for (... in ...) 문은 if 문 (forin)으로 필터링해야합니다."라고 불평합니다.
Yennefer 19.04.08


43

허용되는 대답은 플랫 양식 구조에 맞지만 원래 질문에 완전히 대답하지는 않습니다. 웹 페이지에는 중첩 된 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();
        }
    });
}

것입니다 instanceof항상 타이프 라이터로 transpiled 후 작동?
주목할만한

@ the-notable instanceof은 TypeScript 전용 키워드가 아닙니다 ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) class데이터 유형 도 아닙니다 .
Keenan Diggs 19

8

@Marcos 답변을 사용하여 formGroup을 매개 변수로 전달하는 함수를 만들었으며 모든 formGroup 자식 컨트롤을 더티로 표시하여 서비스 내부에 넣는 코드 주변의 더 많은 곳에서 사용할 수 있도록합니다.

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

도움이 되길 바랍니다;)


완전한! clearValidators, untouch 등에 유사한 기능과 함께 서비스에 추가되었습니다. 중첩 된 컨트롤에 대한 재귀 검사를 추가하고 싶을 수 있지만 지금은 작동합니다. 감사!
mc01

7

get Angular 8에서 양식의 특정 값을 검색하기 위해 더 이상 함수가 작동하지 않는 것 같습니다 . 그래서 이것이 @Liviu Ilea의 답변을 기반으로 해결 한 방법입니다.

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

확실합니까? API 문서에는 Abstract Control ( angular.io/api/forms/AbstractControl#get )에 대한 get 메서드가 이미 있습니다. 아직 마이그레이션하지 않았습니다. 지금은 (⊙_ ◎) 무서워
앨런 Grosz에게

@AlanGrosz 예, 다시 작성할 때도 보았지만 콘솔의 모든 줄을 인쇄 할 때도 개체에서 get 메서드를 찾을 수 없었습니다. 문서가 뒤에 있다고 생각합니다. 행운을 빕니다!
Michelangelo

나는 그들이 그것을 제거했다고 생각하지 않는다. Angular 8에서 나를 위해 일한다. 또한 그것은 문서 angular.io/api/forms/AbstractControl#get
Laszlo Sarvold

5

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


4

이것이 나를 위해 일하는 것입니다.

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

1

나는 이것을 만들기 위해이 함수를 생성한다 * 나는 'order'라는 이름의 컨트롤을 가지고 있고 그에게 인덱스를 전달한다.

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


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

0

@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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.