【问题标题】:all form controls are valid but the form is invalid in angular所有表单控件都有效,但表单在角度无效
【发布时间】:2020-10-24 00:00:40
【问题描述】:

我为我的注册表单创建了一个 asyc 验证器,并将其连接到我的 express 应用程序以便它返回正确的响应,现在我处于所有表单控件都有效但表单本身不有效的最后一步得到验证并且提交按钮保持禁用状态,这是我的代码

register.component.ts

    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    import { AuthService } from '../auth.service';
    import { UniqueEmail } from '../validators/unique-email';
    @Component({
      selector: 'app-register',
      templateUrl: './register.component.html',
      styleUrls: ['./register.component.scss'],
    })
    export class RegisterComponent implements OnInit{
      registerForm: FormGroup
      constructor(
        private fb: FormBuilder,
        private auth: AuthService,
       private uniqueEmail: UniqueEmail
      ) {}
    
      ngOnInit(){
        this.registerForm = this.fb.group({
          firstName: [null, [Validators.required, Validators.minLength(2)]],
          lastName: [null, [Validators.required, Validators.minLength(2)]],
          email: [
            null,
            [Validators.required, Validators.email],
            this.uniqueEmail.validateEmailNotTaken.bind(this.uniqueEmail)
          ],
          phoneNumber: [null, Validators.required],
          password: [null, [Validators.required, Validators.minLength(8)]],
        });
      
    
        this.registerForm.valueChanges.subscribe(data =>  {
          const invalid = [];
          const controls = this.registerForm.controls;
          for (const name in controls) {
              if (controls[name].invalid) {
                  invalid.push(name);
              }
          }
    
          console.log (invalid);
          console.log(this.registerForm.valid)
      });
    
      }
    
      onSubmit() {
        this.auth.register(this.registerForm.value).subscribe(console.log);
      }
    }

register.component.html

    <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
      <mat-card class="shipping-card">
        <mat-card-header>
          <mat-card-title>Manager Registration</mat-card-title>
        </mat-card-header>
        <mat-card-content>
          <div class="row">
            <div class="col">
              <mat-form-field class="full-width">
                <input
                  matInput
                  placeholder="First name"
                  formControlName="firstName"
                  type="text"
                />
                <mat-error
                  *ngIf="registerForm.controls['firstName'].hasError('minlength')"
                >
                  min length is 2 characters
                </mat-error>
                <mat-error
                  *ngIf="registerForm.controls['firstName'].hasError('required')"
                >
                  First name is <strong>required</strong>
                </mat-error>
              </mat-form-field>
            </div>
            <div class="col">
              <mat-form-field class="full-width">
                <input
                  matInput
                  placeholder="Last name"
                  formControlName="lastName"
                  type="text"
                />
                <mat-error
                  *ngIf="registerForm.controls['lastName'].hasError('minlength')"
                >
                  min length is 2 characters
                </mat-error>
                <mat-error
                  *ngIf="registerForm.controls['lastName'].hasError('required')"
                >
                  Last name is <strong>required</strong>
                </mat-error>
              </mat-form-field>
            </div>
          </div>
          <div class="row">
            <div class="col">
              <mat-form-field class="full-width">
                <input
                  matInput
                  placeholder="Email"
                  formControlName="email"
                  type="email"
                />
                <mat-error
                  *ngIf="registerForm.controls['email'].hasError('required')"
                >
                  Email is <strong>required</strong>
                </mat-error>
                <mat-error
                *ngIf="registerForm.controls['email'].hasError('emailTaken')"
              >
                this email is used before
              </mat-error>
                <mat-error *ngIf="registerForm.controls['email'].hasError('email')">
                  please enter a valid email
                </mat-error>
              </mat-form-field>
            </div>
            <div class="col">
              <mat-form-field class="full-width">
                <input
                  matInput
                  placeholder="Phone Number"
                  formControlName="phoneNumber"
                  type="text"
                />
                <mat-error
                  *ngIf="registerForm.controls['phoneNumber'].hasError('required')"
                >
                  Phone Number is <strong>required</strong>
                </mat-error>
              </mat-form-field>
            </div>
          </div>
          <div class="row">
            <div class="col">
              <mat-form-field class="full-width">
                <input
                  matInput
                  placeholder="Password"
                  formControlName="password"
                  type="password"
                />
                <mat-error
                  *ngIf="registerForm.controls['password'].hasError('required')"
                >
                  Password is <strong>required</strong>
                </mat-error>
                <mat-error
                  *ngIf="registerForm.controls['password'].hasError('minlength')"
                >
                  min length is 8 characters
                </mat-error>
              </mat-form-field>
            </div>
            <div class="col"></div>
          </div>
        </mat-card-content>
        <mat-card-actions>
          <button
            mat-raised-button
            color="primary"
            type="submit"
            [disabled]="!registerForm.valid"
          >
            Submit
          </button>
        </mat-card-actions>
      </mat-card>
    </form>

auth.service.ts

    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { map } from 'rxjs/operators';
    import { environment } from 'src/environments/environment';
    
    @Injectable({
      providedIn: 'root',
    })
    export class AuthService {
      constructor(private http: HttpClient) {}
    
      registerUrl = `${environment.apiUrl}/api/manager/register`;
      loginUrl = `${environment.apiUrl}/api/manager/login`;
      checkEmailNotTakenUrl = `${environment.apiUrl}/api/manager/unique-email`;
    
      register(formInfo) {
        return this.http.post(this.registerUrl, formInfo);
      }
    
      login(formInfo) {
        return this.http.post(this.loginUrl, formInfo).pipe(
          map((result) => {
            localStorage.setItem('access_token', result['token']);
            return result;
          })
        );
      }
    
      logout() {
        localStorage.removeItem('access_token');
      }
    
      public get loggedIn(): boolean {
        return localStorage.getItem('access_token') !== null;
      }
    
      checkEmailNotTaken(email) {
        return this.http.post(this.checkEmailNotTakenUrl, { email: email });
      }
    }

unique-email.ts

    import { AbstractControl } from '@angular/forms';
    import { map, tap } from 'rxjs/operators';
    import { AuthService } from '../auth.service';
    import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root',
    })
    export class UniqueEmail {
      constructor(private auth: AuthService) {}
    
      validateEmailNotTaken(control: AbstractControl) {
        return this.auth.checkEmailNotTaken(control.value).pipe(
          tap(console.log),
          map((res) => {
            return res == { emailTaken: true } ? null : { emailTaken: true };
          }),
          tap(console.log),
        );
      }
    }

这张照片总结了数组包含无效控件的问题,布尔值表示表单的有效性 app inteface

【问题讨论】:

    标签: angular validation angular-forms


    【解决方案1】:

    我通过检查禁用提交按钮中的表单控件验证器找到了解决此问题的方法,但我仍然不知道问题的真正原因是什么

    [disabled]="registerForm.controls['password'].hasError('minlength') || registerForm.controls['password'].hasError('required') || registerForm.controls['phoneNumber'].hasError('required') || registerForm.controls['email'].hasError('email') || registerForm.controls['email'].hasError('emailTaken') || registerForm.controls['email'].hasError('required') || registerForm.controls['lastName'].hasError('required') || registerForm.controls['lastName'].hasError('minlength') || registerForm.controls['firstName'].hasError('required') || registerForm.controls['firstName'].hasError('minlength')"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      相关资源
      最近更新 更多