响应式表单验证:无法将状态更改为有效

时间:2018-08-07 01:37:11

标签: javascript angular forms

所以我正在处理反应式注册表单。在此示例中,我具有表单控件firstName,并且此表单控件具有验证程序required

当我离开名字输入并且在输入中未输入任何内容时,我想显示一条错误消息。当我在输入中不输入任何内容并按Tab时,它会显示我打算使用的红色边框底线,并且具有类ng-invalid(CSS中提到了红色边框底线,请参见下文)。

但是,当我返回到first name输入并输入字符时,ng-invalid不会消失,并且在底部的li错误消息也不会消失。有人知道是什么原因造成的,我该如何解决?

这是表格的样子,在模式的底部,我有一个<UL>,其中包含所有错误。在devtools中,我可以看到在firstname输入中输入字符时ng-invalid类不会消失

enter image description here

模板

    <form class="form" [formGroup]="mySignupForm" (ngSubmit)="onSignupSubmit()">
            <div class="row">
                <div class="col-1-of-2">
                    <div class="form__group">
                        <input
                                id="firstName"
                                class="form__input"
                                type="text"
                                placeholder="First Name"
                                formControlName="firstName"
required
                                >

                        <label
                                class="form__label"
                                for="firstName">First Name
                        </label>
                    </div>
                    <div class="form__group">
                        <input
                                id="username"
                                (blur)="checkUniqueUsername()"
                                [class.invalid-input]="uniqueUsernameMessage"
                                name="username"
                                class="form__input"
                                type="text"
                                placeholder="Username"
                                formControlName="username"
                        >
                        <!--<div class="p-3 username-error" *ngIf="uniqueUsernameMessage">This username already exists</div>-->
                        <label class="form__label" for="username">Username</label>
                    </div>
                    <div class="form__group">
                        <input
                                id="password1"
                                name="password1"
                                class="form__input"
                                type="password"
                                placeholder="Password"
                                formControlName="password1"
                                pattern="^.*(?=.{4,10})(?=.*\d)(?=.*[a-zA-Z]).*$"
                        >
                        <!--<div class="bg-danger p-3 password-error" *ngIf="mySignupForm.get('password1').errors?.pattern && mySignupForm.get('password1').touched"> FAIL</div>-->
                        <label class="form__label" for="password1">Password</label>
                    </div>
                    <div class="form__group birth">
                        <input
                                type="text"
                                [minDate]="{year: 1900, month: 1, day: 1}"
                                name="birthDate" id="birthDate"
                                class="form__input birth__input"
                                formControlName="birthDate"
                                ngbDatepicker
                                #d="ngbDatepicker"
                                placeholder="YYYY-MM-DD"
                                required
                        />
                        <div class="birth__button-box">
                            <button class="btn btn--primary birth__button" (click)="d.toggle()">Pick Birth Date</button>
                        </div>
                        <!--<ngb-datepicker [minDate]="{year: 1900, month: 1, day: 1}" [maxDate]="{year: 2016, month: 12, day: 31}" id="birthDate" #d formControlName="birthDate"></ngb-datepicker>-->
                    </div>
                </div>
                <div class="col-1-of-2 sec-col">
                    <div class="form__group">
                        <input id="lastName" name="lastName" class="form__input" type="text" placeholder="Last name:" formControlName="lastName">
                        <label class="form__label" for="lastName">Last Name</label>
                    </div>
                    <div class="form__group">
                        <input id="email" (keyup)="doSomething()" name="email" class="form__input" type="text" placeholder="Email:" formControlName="email">
                        <!--<div class="bg-danger p-3 email-error" *ngIf="mySignupForm.get('email').errors?.email && mySignupForm.get('email').touched"> This is not a valid email address</div>-->
                        <label class="form__label" for="email">Email</label>
                    </div>
                    <div class="form-group">
                        <input id="password2" name="password2" class="form__input" type="password" placeholder="Repeat Password" formControlName="password2" pattern="^.*(?=.{4,10})(?=.*\d)(?=.*[a-zA-Z]).*$">
                        <!--<div class="bg-danger p-3 password-error" *ngIf="!equalPasswords() && mySignupForm.get('password2').touched"> Both passwords have to be equal.</div>-->
                        <label class="form__label" for="password2">Repeat password</label>
                    </div>
                    <div class="form-group">
                        <select class="form__input" name="country" id="country" formControlName="country">
                            <option  *ngFor="let country of countries">{{country}}</option>
                        </select>
                    </div>
                </div>
            </div>
            <div class="row errors">
                <ul class="errors__list">
                    <li *ngIf="firstName?.errors.required && (firstName?.dirty || firstName?.touched)" class="errors__item">First name is required</li>
                    <li *ngIf="lastName?.errors.required && (lastName?.dirty || lastName?.touched)" class="errors__item">Last name is required</li>
                    <li *ngIf="email?.errors.required && (email?.dirty || email?.touched)" class="errors__item">Email address is required</li>
                    <li *ngIf="email?.errors.email && (email?.dirty || email?.touched)" class="errors__item">You need a valid email address</li>
                    <li *ngIf="password1?.errors.required && (password1?.dirty || password1?.touched)" class="errors__item">Password is required</li>
                    <li *ngIf="username?.errors.required && (username?.dirty || username?.touched)" class="errors__item">Username is required</li>
                    <li *ngIf="country?.errors.required && (country?.dirty || email?.touched)" class="errors__item">Country is required</li>
                    <li *ngIf="birthDate?.errors.required && (birthDate?.dirty || birthDate?.touched)" class="errors__item">Date of birth is required</li>
                    <li *ngIf="password1?.touched && password2?.touched && !equalPasswords()" class="errors__item">Passwords need to match</li>
                    <li *ngIf="uniqueUsernameMessage" class="errors__item">Username needs to be unique</li>
                </ul>
            </div>
            <button class="btn btn-secondary" (click)="getFormValidationErrors()">Submit</button>
            <!--<button class="btn btn-secondary" [disabled]="!mySignupForm.valid && !equalPasswords() && !uniqueUsernameMessage" type="submit">Submit</button>-->
            <button type="button" class="btn btn-outline-secondary ml-auto" (click)="c('Close click')">Close</button>
        </form>

组件

get firstName() { return this.mySignupForm.get('firstName'); }
    get lastName() { return this.mySignupForm.get('lastname'); }
    get username() { return this.mySignupForm.get('username'); }
    get email() { return this.mySignupForm.get('email'); }
    get password1() { return this.mySignupForm.get('password1'); }
    get password2() { return this.mySignupForm.get('password2'); }
    get birthDate() { return this.mySignupForm.get('birthDate'); }
    get country() { return this.mySignupForm.get('country'); }


    ngOnInit(){
        this.mySignupForm = new FormGroup({
            firstName: new FormControl(null, Validators.required),
            lastName: new FormControl(null, Validators.required),
            username: new FormControl(null, [Validators.required, Validators.minLength(6)]),
            birthDate: new FormControl(null, Validators.required),
            password2: new FormControl(null, Validators.required),
            email: new FormControl(null, [Validators.required, Validators.email]),
            password1: new FormControl(null, Validators.required),
            country: new FormControl(null, Validators.required)
        });
    }

SCSS文件

input.ng-valid.ng-touched, input.ng-valid.ng-dirty {
  border-bottom: 3px solid green;
}

input.ng-invalid.ng-touched , input.ng-invalid.ng-dirty{
  border-bottom: 3px solid red;

.valid-input {
  border-bottom: 3px solid green;
}

.invalid-input {
  border-bottom: 3px solid red !important;
}

1 个答案:

答案 0 :(得分:1)

请从错误状态中删除.touched。这是我们将如何实施

<div *ngIf="firstName.dirty && firstName.errors && firstName.hasError('required')" class="errorClass w-100">
                            Display error message
</div>