javascript - 响应式(Reactive)表单验证 : unable to change state to valid

标签 javascript angular forms

所以我正在研究一个响应式(Reactive)注册表单。在此示例中,我有表单控件 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;
}

最佳答案

请从错误条件中删除 .touched。以下是我们将如何实现

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

关于javascript - 响应式(Reactive)表单验证 : unable to change state to valid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51717645/

相关文章:

javascript - 不可枚举的属性出现在 Chrome 的 for...in 循环中

javascript - 使用 OnClick 函数 JavaScript 删除 Firebase 节点

javascript - 仅当禁用按钮时,如何才能在 Angular 模板 (.html) 中显示工具提示?

javascript - Angular NGRX 在从效果中调度 Action 时无法将数据传递给 reducer 。出现错误 - TypeError : Cannot freeze

javascript - Symfony2 : manually submit a form without class via AJAX

内联事件处理程序中未调用 JavaScript

javascript - 如果我在 javascript 中重写 window.onerror 我应该返回 true 还是 false?

javascript - 使用 jquery 切换时,按钮会一直轻推

javascript - 未捕获的类型错误 : Cannot read property 'parse' of undefined when requiring a library

php - 表单未提交到数据库