কৌনিক 2 ফর্মগ্রুপ থেকে সমস্ত বৈধতা ত্রুটি পান


92

এই কোড দেওয়া:

this.form = this.formBuilder.group({
      email: ['', [Validators.required, EmailValidator.isValid]],
      hasAcceptedTerms: [false, Validators.pattern('true')]
    });

আমি কীভাবে সমস্ত বৈধতা ত্রুটি পেতে পারি this.form?

আমি ইউনিট পরীক্ষা লিখছি এবং আসক্তি বার্তায় প্রকৃত বৈধতা ত্রুটিগুলি অন্তর্ভুক্ত করতে চাই।


ভ্যালিডেটর.প্যাটটার্ন ('সত্য') এর পরিবর্তে আপনি চেকবক্সটি চেকবক্সটি প্রয়োগ করতে Validators.requiredTrue ব্যবহার করতে পারেন / করতে পারেন।
অকার্যকর

উত্তর:


146

আমি একই সমস্যার মুখোমুখি হয়েছি এবং সমস্ত বৈধতা ত্রুটি খুঁজে বের করার জন্য এবং সেগুলি প্রদর্শনের জন্য, আমি পরবর্তী পদ্ধতিটি লিখেছিলাম:

getFormValidationErrors() {
  Object.keys(this.productForm.controls).forEach(key => {

  const controlErrors: ValidationErrors = this.productForm.get(key).errors;
  if (controlErrors != null) {
        Object.keys(controlErrors).forEach(keyError => {
          console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
        });
      }
    });
  }

ফর্মের নামটি productFormআপনার পরিবর্তন করা উচিত।

এটি পরবর্তী পদ্ধতিতে কাজ করে: {[p: string]: AbstractControl}ত্রুটির বিবরণ পেতে আমরা ফর্ম্যাট থেকে আমাদের সমস্ত নিয়ন্ত্রণ ফর্ম্যাট থেকে পাই এবং প্রতিটি ত্রুটি কী দ্বারা পুনরাবৃত্তি করি। এটি nullত্রুটির মানগুলি এড়িয়ে যায় ।

এটি টেম্পলেট ভিউতে বৈধতা ত্রুটিগুলি প্রদর্শনের জন্যও পরিবর্তন করা যেতে পারে, console.log(..)আপনার যা প্রয়োজন তা প্রতিস্থাপন করুন ।


4
একই প্যাটার্নে ফর্মআরয়ের জন্য উপরের পদ্ধতিটি কীভাবে প্রসারিত করবেন?
মোহাম্মদ শরাফ আলী

আপনি কি ' + controlErrors[keyErrors];পরিবর্তে বোঝাতে চেয়েছিলেন ', controlErrors[keyErrors];?
রায়য়ান

@ রাইয়ানম না, মুদ্রণের মতো বস্তু বা স্ট্রিংয়ের মানের মতো আলাদা।
অ্যালেক্স এফিমভ

আমি ValidationErrorsকৌনিক 2 এ কোথায় আমদানি করতে পারি ?
sauu

import { ValidationErrors } from '@angular/forms';
ক্রেগ ওয়েন

31

এটি FormGroupঅভ্যন্তরীণ সমর্থন সহ সমাধান ( এখানে এখানে )

পরীক্ষিত: কৌণিক 4.3.6

গেম-ফর্ম-বৈধতা-त्रुटী

import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms';

export interface AllValidationErrors {
  control_name: string;
  error_name: string;
  error_value: any;
}

export interface FormGroupControls {
  [key: string]: AbstractControl;
}

export function getFormValidationErrors(controls: FormGroupControls): AllValidationErrors[] {
  let errors: AllValidationErrors[] = [];
  Object.keys(controls).forEach(key => {
    const control = controls[ key ];
    if (control instanceof FormGroup) {
      errors = errors.concat(getFormValidationErrors(control.controls));
    }
    const controlErrors: ValidationErrors = controls[ key ].errors;
    if (controlErrors !== null) {
      Object.keys(controlErrors).forEach(keyError => {
        errors.push({
          control_name: key,
          error_name: keyError,
          error_value: controlErrors[ keyError ]
        });
      });
    }
  });
  return errors;
}

উদাহরণ ব্যবহার করে :

if (!this.formValid()) {
  const error: AllValidationErrors = getFormValidationErrors(this.regForm.controls).shift();
  if (error) {
    let text;
    switch (error.error_name) {
      case 'required': text = `${error.control_name} is required!`; break;
      case 'pattern': text = `${error.control_name} has wrong pattern!`; break;
      case 'email': text = `${error.control_name} has wrong email format!`; break;
      case 'minlength': text = `${error.control_name} has wrong length! Required length: ${error.error_value.requiredLength}`; break;
      case 'areEqual': text = `${error.control_name} must be equal!`; break;
      default: text = `${error.control_name}: ${error.error_name}: ${error.error_value}`;
    }
    this.error = text;
  }
  return;
}

4
কৌণিক 5 পরিবর্তন - নিয়ন্ত্রন নিয়ন্ত্রণের ত্রুটি: বৈধতা ত্রুটি = form.controls [কী] er
ক্রিস কিলটন

পরামর্শের উপর truthy জন্য চেক করতে controlErrors অর্থাত if (controlErrors) {পরীক্ষণ শুধুমাত্র যেমন nullএকটি ত্রুটি দেব হলে ত্রুটিundefined
mtholen

8

এটি অন্য একটি রূপ যা ত্রুটিগুলি পুনরাবৃত্তভাবে সংগ্রহ করে এবং কোনও বহিরাগত লাইব্রেরির উপর নির্ভর করে না lodash(কেবলমাত্র ES6):

function isFormGroup(control: AbstractControl): control is FormGroup {
  return !!(<FormGroup>control).controls;
}

function collectErrors(control: AbstractControl): any | null {
  if (isFormGroup(control)) {
    return Object.entries(control.controls)
      .reduce(
        (acc, [key, childControl]) => {
          const childErrors = collectErrors(childControl);
          if (childErrors) {
            acc = {...acc, [key]: childErrors};
          }
          return acc;
        },
        null
      );
  } else {
    return control.errors;
  }
}

6

একটি কৌণিক ফর্ম থেকে সমস্ত ত্রুটিগুলি পুনরুদ্ধার করার জন্য পুনরাবৃত্তির উপায় , কোনও ধরণের সূত্র কাঠামো তৈরির পরে ফর্মটি থেকে সমস্ত ত্রুটিগুলি পুনরুদ্ধার করার উপায় নেই। এটি ডিবাগিং উদ্দেশ্যে নয় ত্রুটিগুলি ষড়যন্ত্র করার জন্যও খুব দরকারী।

কৌণিক 9 এর জন্য পরীক্ষিত

getFormErrors(form: AbstractControl) {
    if (form instanceof FormControl) {
        // Return FormControl errors or null
        return form.errors ?? null;
    }
    if (form instanceof FormGroup) {
        const groupErrors = form.errors;
        // Form group can contain errors itself, in that case add'em
        const formErrors = groupErrors ? {groupErrors} : {};
        Object.keys(form.controls).forEach(key => {
            // Recursive call of the FormGroup fields
            const error = this.getFormErrors(form.get(key));
            if (error !== null) {
                // Only add error if not null
                formErrors[key] = error;
            }
        });
        // Return FormGroup errors or null
        return Object.keys(formErrors).length > 0 ? formErrors : null;
    }
}

আমি কৌনিক 7 ব্যবহার করছি এবং আপনার কোডে দুটি পরিবর্তন form.errors ?? nullকরেছি : আমাকে অপসারণ করতে হবে ?? এটি সংকলন করার জন্য। আরও গুরুত্বপূর্ণ বিষয়, ফর্মগ্রুপ চেক শর্তে, আমি যুক্ত করেছি || formParameter instanceof FormArrayযা সত্যই আমার অ্যাপ্লিকেশনটি খুলল। ধন্যবাদ!
টাইলার ফোরসিথে

6

অথবা আপনি কেবল গভীর এবং গতিশীল ফর্ম থেকে সমস্ত ত্রুটি পেতে এই লাইব্রেরিটি ব্যবহার করতে পারেন।

npm i @naologic/forms

আপনি যদি নিজের ফর্মগুলিতে স্থির ফাংশনটি ব্যবহার করতে চান

import {NaoFormStatic} from '@naologic/forms';
...
const errorsFlat = NaoFormStatic.getAllErrorsFlat(fg); 
console.log(errorsFlat);

আপনি যদি ব্যবহার করতে চান তবে NaoFromGroupআমদানি করে এটি ব্যবহার করতে পারেন

import {NaoFormGroup, NaoFormControl, NaoValidators} from '@naologic/forms';
...
    this.naoFormGroup = new NaoFormGroup({
      firstName: new NaoFormControl('John'),
      lastName: new NaoFormControl('Doe'),
      ssn: new NaoFormControl('000 00 0000', NaoValidators.isSSN()),
    });

   const getFormErrors = this.naoFormGroup.getAllErrors();
   console.log(getFormErrors);
   // --> {first: {ok: false, isSSN: false, actualValue: "000 00 0000"}}

সম্পূর্ণ ডকুমেন্টেশন পড়ুন


2

@ মিক্সারওআইডি প্রতিক্রিয়াটির ভিত্তিতে , এখানে উপাদান হিসাবে আমার চূড়ান্ত সমাধান (সম্ভবত আমি একটি গ্রন্থাগার তৈরি করব)। আমি ফর্মআরয়ের সমর্থন করি:

import {Component, ElementRef, Input, OnInit} from '@angular/core';
import {FormArray, FormGroup, ValidationErrors} from '@angular/forms';
import {TranslateService} from '@ngx-translate/core';

interface AllValidationErrors {
  controlName: string;
  errorName: string;
  errorValue: any;
}

@Component({
  selector: 'app-form-errors',
  templateUrl: './form-errors.component.html',
  styleUrls: ['./form-errors.component.scss']
})
export class FormErrorsComponent implements OnInit {

  @Input() form: FormGroup;
  @Input() formRef: ElementRef;
  @Input() messages: Array<any>;

  private errors: AllValidationErrors[];

  constructor(
    private translateService: TranslateService
  ) {
    this.errors = [];
    this.messages = [];
  }

  ngOnInit() {
    this.form.valueChanges.subscribe(() => {
      this.errors = [];
      this.calculateErrors(this.form);
    });

    this.calculateErrors(this.form);
  }

  calculateErrors(form: FormGroup | FormArray) {
    Object.keys(form.controls).forEach(field => {
      const control = form.get(field);
      if (control instanceof FormGroup || control instanceof FormArray) {
        this.errors = this.errors.concat(this.calculateErrors(control));
        return;
      }

      const controlErrors: ValidationErrors = control.errors;
      if (controlErrors !== null) {
        Object.keys(controlErrors).forEach(keyError => {
          this.errors.push({
            controlName: field,
            errorName: keyError,
            errorValue: controlErrors[keyError]
          });
        });
      }
    });

    // This removes duplicates
    this.errors = this.errors.filter((error, index, self) => self.findIndex(t => {
      return t.controlName === error.controlName && t.errorName === error.errorName;
    }) === index);
    return this.errors;
  }

  getErrorMessage(error) {
    switch (error.errorName) {
      case 'required':
        return this.translateService.instant('mustFill') + ' ' + this.messages[error.controlName];
      default:
        return 'unknown error ' + error.errorName;
    }
  }
}

এবং এইচটিএমএল:

<div *ngIf="formRef.submitted">
  <div *ngFor="let error of errors" class="text-danger">
    {{getErrorMessage(error)}}
  </div>
</div>

ব্যবহার:

<app-form-errors [form]="languageForm"
                 [formRef]="formRef"
                 [messages]="{language: 'Language'}">
</app-form-errors>

2

এটি ব্যবহার করে দেখুন, এটি ফর্মের সমস্ত নিয়ন্ত্রণের জন্য বৈধতা বলবে:

validateAllFormControl(formGroup: FormGroup) {         
  Object.keys(formGroup.controls).forEach(field => {  
    const control = formGroup.get(field);             
    if (control instanceof FormControl) {             
      control.markAsTouched({ onlySelf: true });
    } else if (control instanceof FormGroup) {        
      this.validateAllFormControl(control);            
    }
  });
}

1
export class GenericValidator {
    constructor(private validationMessages: { [key: string]: { [key: string]: string } }) {
    }

processMessages(container: FormGroup): { [key: string]: string } {
    const messages = {};
    for (const controlKey in container.controls) {
        if (container.controls.hasOwnProperty(controlKey)) {
            const c = container.controls[controlKey];
            if (c instanceof FormGroup) {
                const childMessages = this.processMessages(c);
                // handling formGroup errors messages
                const formGroupErrors = {};
                if (this.validationMessages[controlKey]) {
                    formGroupErrors[controlKey] = '';
                    if (c.errors) {
                        Object.keys(c.errors).map((messageKey) => {
                            if (this.validationMessages[controlKey][messageKey]) {
                                formGroupErrors[controlKey] += this.validationMessages[controlKey][messageKey] + ' ';
                            }
                        })
                    }
                }
                Object.assign(messages, childMessages, formGroupErrors);
            } else {
                // handling control fields errors messages
                if (this.validationMessages[controlKey]) {
                    messages[controlKey] = '';
                    if ((c.dirty || c.touched) && c.errors) {
                        Object.keys(c.errors).map((messageKey) => {
                            if (this.validationMessages[controlKey][messageKey]) {
                                messages[controlKey] += this.validationMessages[controlKey][messageKey] + ' ';
                            }
                        })
                    }
                }
            }
        }
    }
    return messages;
}
}

আমি এটি ডিবোরাক থেকে নিয়েছিলাম এবং এটি কিছুটা সংশোধন করেছি।


1
// IF not populated correctly - you could get aggregated FormGroup errors object
let getErrors = (formGroup: FormGroup, errors: any = {}) {
  Object.keys(formGroup.controls).forEach(field => {
    const control = formGroup.get(field);
    if (control instanceof FormControl) {
      errors[field] = control.errors;
    } else if (control instanceof FormGroup) {
      errors[field] = this.getErrors(control);
    }
  });
  return errors;
}

// Calling it:
let formErrors = getErrors(this.form);

0

আপনি this.for.erferences বৈশিষ্ট্যটি পুনরাবৃত্তি করতে পারেন


14
আমি অনুমান করি যে this.form.errorsকেবলমাত্র এর জন্য বৈধতার ত্রুটিগুলি প্রদান করে this.form, এর জন্য নয় this.form.controls। আপনি ফর্মগ্রুপস এবং তার বাচ্চাদের (ফর্মগ্রুপস, ফর্মকন্ট্রোলস এবং ফর্মআরাইয়ের স্বেচ্ছাসেবী) আলাদাভাবে বৈধতা দিতে পারেন। সমস্ত ত্রুটি আনার জন্য, আমার মনে হয় আপনার তাদের পুনরাবৃত্তভাবে জিজ্ঞাসা করা উচিত।
Risto Välimäki

0

একটি বৃহত ফর্মগ্রুপ গাছের জন্য, আপনি গাছটি পরিষ্কার করতে লোডাশ ব্যবহার করতে পারেন এবং ত্রুটি সহ কেবল নিয়ন্ত্রণের একটি গাছ পেতে পারেন। এটি শিশু নিয়ন্ত্রণের মাধ্যমে পুনরাবৃত্তি করে (উদাহরণস্বরূপ ব্যবহার করে allErrors(formGroup)), এবং নিয়ন্ত্রণগুলির কোনও সম্পূর্ণ-বৈধ উপ-গ্রুপকে ছাঁটাই করে করা হয়:

private isFormGroup(control: AbstractControl): control is FormGroup {
  return !!(<FormGroup>control).controls;
}

// Returns a tree of any errors in control and children of control
allErrors(control: AbstractControl): any {
  if (this.isFormGroup(control)) {
    const childErrors = _.mapValues(control.controls, (childControl) => {
      return this.allErrors(childControl);
    });

    const pruned = _.omitBy(childErrors, _.isEmpty);
    return _.isEmpty(pruned) ? null : pruned;
  } else {
    return control.errors;
  }
}

-2

আমি কৌণিক 5 ব্যবহার করছি এবং আপনি ফর্মগ্রুপ উদাহরণস্বরূপ আপনার ফর্মের স্থিতি সম্পত্তিটি পরীক্ষা করতে পারেন

this.form = new FormGroup({
      firstName: new FormControl('', [Validators.required, validateName]),
      lastName: new FormControl('', [Validators.required, validateName]),
      email: new FormControl('', [Validators.required, validateEmail]),
      dob: new FormControl('', [Validators.required, validateDate])
    });

এই ক্ষেত্রটি সমস্ত বৈধতা বিধি পাস না করে this.for.status "ইনভ্যালিড" হবে।

সর্বোত্তম অংশটি এটি রিয়েল-টাইমে পরিবর্তনগুলি সনাক্ত করে।


4
হ্যাঁ তবে আমাদের একটি সম্পূর্ণ ফর্মগ্রুপের ত্রুটিগুলি পাওয়া দরকার, এটি বৈধ নয় তা কেবল জানতে হবে না
মোতসেম এমকে

ওপির বৈধতা বার্তাগুলি দরকার, যা স্থিতির সম্পত্তিতে অন্তর্ভুক্ত নয়, কারণ এটি কেবল একটি বুলিয়ান।
স্টেফান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.