Angular Не отображаются сообщения о проверке реактивных форм - PullRequest
0 голосов
/ 06 августа 2020

Я использую Angular 8, и я использовал реактивную форму для своей страницы регистрации. А также использовал Angular Material Stepper Ui для разработки формы.

Это файл signup.component.ts.

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';
import { UserSignUp } from '../shared/signupForm';
import { AuthService } from '../services/auth.service';

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

  signupForm: FormGroup;
  signup: UserSignUp;
  @ViewChild('form', {
    static: true
  }) signupFormDirective;
  errMsg = '';
  isSuccessful = false;
  isLoginFailed = false;
  isLinear = true;

  formErrors = {
    'username': '',
    'password': '',
    'email': '',
    'firstName' : '',
    'lastName' : '',
    'designation': '',
    'organization': '',
    'address': '',
    'contactNo': ''
  };

  validationMessages = {
    'username' : {
      'required'  :   'Username Name is Required.',
      'minlength' :   'Username must be at least 3 characters long..',
      'maxlength' :   'Username cannot be more than 25 characters long'
    },
    'password' : {
      'required'  :   'Password is required',
      'minlength' :   'Password must be at least 5 Characters',
      'maxlength' :   'Password cannot be more than 25 characters long'
    },
    'email' : {
      'required'  :   'Email is Required.',
      'email'     :   'Invalid Email'
    },
    'firstName' : {
      'required'  :   'First Name is required'
    },
    'lastName' : {
      'required'  :   'Last Name is required.'
    },
    'designation' : {
      'required'  :   'Designation is Required.'
    },
    'organization' : {
      'required'  :   'Organization is Required.'
    },
    'address' : {
      'required'  :   'First Name is Required.'
    },
    'ContactNo' : {
      'required'  :   'First Name is Required.',
      'pattern'   :   'Contact No. should only contain Numbers '
    }
  };


  constructor(private fb: FormBuilder, private authService: AuthService) {
    this.createForm();
   }

  ngOnInit() {}

  get formArray(): AbstractControl | null { return this.signupForm.get('formArray'); }


  createForm() {
    this.signupForm = this.fb.group({
      formArray: this.fb.array([
        this.fb.group({
          firstName: ['', [Validators.required]],
          lastName: ['', [Validators.required]],
          username : ['', [Validators.required, Validators.minLength(3), Validators.maxLength(25)]],
          email: ['', [Validators.required, Validators.email]],
          designation: ['', [Validators.required]]
        }),
        this.fb.group({
          password : ['', [Validators.required, Validators.minLength(5), Validators.maxLength(25)]],
          organization: ['', [Validators.required]],
          address: ['', [Validators.required]],
          contactNo: ['', [Validators.required]]
        }),
      ])
    });

    this.signupForm.valueChanges
      .subscribe(data => this.onValueChanged(data));

    this.onValueChanged();

  }

  onValueChanged(data?: any) {
    if (!this.signupForm) { return ; }
    const form = this.signupForm;
    for ( const field in this.formErrors) {
      if (this.formErrors.hasOwnProperty(field)) {
        this.formErrors[field] = '';
        const control = form.get(field);
        if (control && control.dirty && !control.valid) {
          const messages = this.validationMessages[field];
          for (const key in control.errors) {
              if (control.errors.hasOwnProperty(key)) {
                this.formErrors[field] += messages[key] + ' ';
              }
          }
        }
      }
    }
  }

  onSubmit() {
    this.signup = this.signupForm.value;
    console.log(this.signup);
    this.authService.register(this.signup)
    .subscribe(
      data => {
        console.log(data);
        this.isSuccessful = true;
        console.log('Successful');
      },
      err => {
        this.errMsg = err.error.message;
        this.isLoginFailed = true;
      }
    );

    this.signupForm.reset({
      username: '',
      password: '',
      email: '',
      firstName: '',
      lastName: '',
      designation: '',
      organization: '',
      address: '',
      contactNo: ''
    });
    this.signupFormDirective.resetForm();
  }



}

А это компонент signup.component. html file.

<div class="container" style="height: 45px;"></div>

<div fxLayoutAlign="space-around center" class="container" >
  <mat-card>
    <div fxLayoutAlign="center">
      <h1>Sign Up</h1>
    </div>
<form novalidate [formGroup]="signupForm" #form="ngForm" (ngSubmit)="onSubmit()">
  <mat-horizontal-stepper [linear]="isLinear"  formArrayName="formArray">
    <mat-step formGroupName="0" [stepControl]="formArray?.get([0])">
        <ng-template matStepLabel>Fill Out Your Details</ng-template>
        <mat-form-field >
          <input matInput formControlName="firstName" placeholder="First Name" type="text" required>
          <mat-error *ngIf="formErrors.firstName">
            {{formErrors.firstName}}
          </mat-error>
        </mat-form-field>
        <mat-form-field >
          <input matInput formControlName="lastName" placeholder="Last Name" type="text" required>
          <mat-error *ngIf="formErrors.lastName">
            {{formErrors.lastName}}
          </mat-error>
        </mat-form-field>
        <p><mat-form-field >
          <input matInput formControlName="username" placeholder="Username" type="text" required>
          <mat-error *ngIf="formErrors.username">
            {{formErrors.username}}
          </mat-error>
        </mat-form-field></p>
        <p><mat-form-field >
          <input matInput formControlName="email" placeholder="Email" type="email" required>
          <mat-error *ngIf="formErrors.email">
            {{formErrors.email}}
          </mat-error>
        </mat-form-field></p>
        <p><mat-form-field >
          <input matInput formControlName="designation" placeholder="Designation" type="text" required>
          <mat-error *ngIf="formErrors.designation">
            {{formErrors.designation}}
          </mat-error>
        </mat-form-field></p>
        <div>
          <button mat-raised-button matStepperNext type="button">Next</button>
        </div>
    </mat-step>
    <mat-step formGroupName="1" [stepControl]="formArray?.get([1])" >
        <ng-template matStepLabel>Few More Steps</ng-template>
        <mat-form-field >
          <input matInput formControlName="password" placeholder="Password" type="password" required>
          <mat-error *ngIf="formErrors.password">
            {{formErrors.password}}
          </mat-error>
        </mat-form-field>
        <p><mat-form-field >
          <input matInput formControlName="organization" placeholder="Organization" type="text" required>
          <mat-error *ngIf="formErrors.organization">
            {{formErrors.organization}}
          </mat-error>
        </mat-form-field></p>
        <p><mat-form-field >
          <textarea matInput formControlName="address" placeholder="Address" type="text" rows="3" cols="10" required ></textarea>
          <mat-error *ngIf="formErrors.address">
            {{formErrors.address}}
          </mat-error>
        </mat-form-field></p>
        <p><mat-form-field >
          <input matInput formControlName="contactNo" placeholder="Contact Number" type="number" required>
          <mat-error *ngIf="formErrors.contactNo">
            {{formErrors.contactNo}}
          </mat-error>
        </mat-form-field></p>
        <div>
          <button mat-raised-button matStepperPrevious class="button-space" type="button">Back</button>
          <button mat-raised-button matStepperNext class="button-space" type="button">Next</button>
        </div>
    </mat-step>
    <mat-step>
      <ng-template matStepLabel>Done</ng-template>
        <p>You are now done.</p>
          <div>
            <button mat-raised-button matStepperPrevious class="button-space">Back</button>
            <button type="submit" mat-raised-button color="primary" class="button-space" [disabled]="signupForm.invalid">Submit</button>
          </div>
    </mat-step>
  </mat-horizontal-stepper>
</form>
</mat-card>
</div>

Проверки выполняются правильно. (При вводе действительного адреса электронной почты поле формы становится красным) Но сообщение о проверке не отображается. Это была идеальная работа до добавления angular шагового материала. Когда я добавил степпер, мне пришлось изменить структуру группы форм, добавить массив форм и разделить форму на части. После этого произошла эта ошибка.

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Я считаю, что ваш подход ошибочен. Ошибка mat внутри поля формы mat отображается, когда ввод ошибочен и прикосновение. Если вы хотите показать ошибку, вы можете использовать, например,

для ввода с уникальной ошибкой

<mat-form-field >
   <input matInput formControlName="firstName" placeholder="First Name" type="text" required>
   <mat-error >
      {{validationMessages.firstName}}
   </mat-error>
</mat-form-field>

для ввода с большим количеством ошибок

<mat-form-field >
   <input matInput formControlName="username" placeholder="Username" type="text" required>
    <mat-error>
      <span *ngFor="let error of signupForm.get('username').errors|keyvalue">
         {{validationMessages.username[error.key]}}
    </span>
  </mat-error>
</mat-form-field>

И можно забыть о подписке на изменения. Обратите внимание, что в последнем случае мы перебираем signupForm.get('username').errors, который является объектом - это причина использования канала keyvalue. Используя канал keyvalue, error.key становится для получения значений: «required», «minlength» или «maxlength»

0 голосов
/ 06 августа 2020

пробовали ли вы выполнить проверку перед отправкой запроса и пометить форму как затронутую, если форма недействительна? вот так:


if(this.signupForm.valid) {
  // send request here
} else {
  this.signupForm.markAllAsTouched()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...