表单验证 Angular 4
Form Validation Angular 4
因此,我尝试使用以下示例:
https://github.com/agiratech/angular4-reactive-form-exercise2/
但是,当我实施它并提交我的表单时,屏幕上的任何地方都没有显示任何错误。您将在下面找到我能想到的所有相关代码。我正在寻找如何让错误显示在屏幕上。我是 Angular 4 的新手,如有任何帮助,我们将不胜感激。
pages.module.ts
import ...
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import ...
import { RegisterComponent } from './register/register.component';
import ...
import { ErrorsComponent } from '../errors.component';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(PagesRoutes),
FormsModule,
ReactiveFormsModule
],
declarations: [
LoginComponent,
RegisterComponent,
LockComponent,
ErrorsComponent
]
})
export class PagesModule {}
register.component.ts
import ...
import {FormGroup, FormBuilder, Validators, FormControl, NgForm} from '@angular/forms';
import ...
import { CustomValidators } from "../../validators/custom-validator.directive";
declare var $:any;
@Component({
moduleId:module.id,
selector: 'register-cmp',
templateUrl: './register.component.html'
})
export class RegisterComponent implements OnInit{
registerForm: FormGroup;
test : Date = new Date();
loading = false;
error = '';
constructor(
private form: FormBuilder,
private router: Router,
private authenticationService: AuthenticationService)
{
this.registerForm = new FormGroup ({
'username':new FormControl('', Validators.required),
'email': new FormControl('', [Validators.required, CustomValidators.validEmail]),
'first_name': new FormControl('', Validators.required),
'last_name': new FormControl('', Validators.required),
'password': new FormControl('', Validators.required),
'confirmPassword': new FormControl('', Validators.required)
});
}
checkFullPageBackgroundImage(){
var $page = $('.full-page');
var image_src = $page.data('image');
if(image_src !== undefined){
var image_container = '<div class="full-page-background" style="background-image: url(' + image_src + ') "/>'
$page.append(image_container);
}
};
ngOnInit() {
this.checkFullPageBackgroundImage();
setTimeout(function(){
// after 1000 ms we add the class animated to the login/register card
$('.card').removeClass('card-hidden');
}, 700)
}
register(registerForm: NgForm) {
console.log(this.registerForm.value);
}
}
register.component.html
<form [formGroup]="registerForm" (ngSubmit)="register(registerForm)">
<div class="card card-plain">
<div class="content">
<div class="form-group">
<input type="text" placeholder="Your First Name" class="form-control" formControlName="first_name">
<errors [control]="registerForm.controls.first_name"></errors>
</div>
<div class="form-group">
<input type="text" placeholder="Your Last Name" class="form-control" formControlName="last_name">
<errors [control]="registerForm.controls.last_name"></errors>
</div>
<div class="form-group">
<input type="text" placeholder="Username" class="form-control" formControlName="username">
<errors [control]="registerForm.controls.username"></errors>
</div>
<div class="form-group">
<input type="email" placeholder="Enter email" class="form-control" formControlName="email">
<errors [control]="registerForm.controls.email"></errors>
</div>
<div class="form-group">
<input type="password" placeholder="Password" class="form-control" formControlName="password">
<errors [control]="registerForm.controls.password"></errors>
</div>
<div class="form-group">
<input type="password" placeholder="Password Confirmation" class="form-control" formControlName="confirmPassword">
<errors [control]="registerForm.controls.confirmPassword"></errors>
</div>
</div>
<div class="footer text-center">
<button [disabled]="loading" type="submit" class="btn btn-fill btn-neutral btn-wd">Create Account</button>
<i *ngIf="loading" class="fa fa-spinner fa-spin fa-fw"></i>
</div>
<errors [control]="registerForm"></errors>
</div>
</form>
errors.component.ts
import { Component, Input } from '@angular/core';
import { AbstractControlDirective, AbstractControl } from '@angular/forms';
@Component({
selector: 'errors',
template: `
<ul *ngIf="showErrors()">
<li class="help-box text-warning" *ngFor="let error of errors()">{{error}}</li>
</ul>
`,
})
export class ErrorsComponent {
private static readonly errorMessages = {
'required': () => 'This field is required',
'minlength': (params) => 'The min number of characters is ' + params.requiredLength,
'maxlength': (params) => 'The max allowed number of characters is ' + params.requiredLength,
'pattern': (params) => 'The required pattern is: ' + params.requiredPattern,
'age': (params) => params.message,
'validEmail': (params) => params.message
};
@Input()
private control: AbstractControlDirective | AbstractControl;
showErrors(): boolean {
return this.control &&
this.control.errors &&
(this.control.dirty || this.control.touched);
}
errors(): string[] {
return Object.keys(this.control.errors)
.map(field => this.getMessage(field, this.control.errors[field]));
}
private getMessage(type: string, params: any) {
return ErrorsComponent.errorMessages[type](params);
}
}
你的例子似乎是基于我在 StackBlitz 中用它做的例子工作的,但是如果你看 errors.component.ts
你会看到它说 this.control.dirty || this.control.touched
,这意味着您需要聚焦然后使用光标模糊输入,或者输入一个值然后退格删除它以进行所需的验证显示。
这是来自 docs and if you click them you can read up on their meaning. So for example dirty 的 FormControl
个属性的列表:
感动
get touched: boolean
A control is marked touched once the user has triggered a blur event on it.
脏
get dirty: boolean
A control is dirty if the user has changed the value in the UI.
Note that programmatic changes to a control's value will not mark it
dirty.
此外,通过查看您的代码,我建议您阅读 Angular 风格指南,并继续阅读 FormBuilder
。在我制作的 StackBlitz 示例中,我将您的 FormGroup
示例切换为使用更简洁的 FormBuilder
。最后,看起来您正在使用 jQuery 到 add/remove 类,但请查看 ngClass。在Angular中不需要jQuery,没有它你也可以做任何你想做的事情。
你可以试试这样的-
内部组件 (.ts) 文件 -
public loginForm: FormGroup = this.builder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.minLength(8), Validators.required]]
});
内部组件 (.html) 文件 -
<div class="l-form-row l-login-form__field-row">
<label
class="o-label l-form-label"
for="email"
>Enter your email</label>
<div class="o-input-container">
<input
class="o-input"
type="text"
name="email"
id="email"
formControlName="email"
placeholder="Email"
><div class="o-input-icon"></div>
</div>
<div
class="o-input-error l-form-error"
eValidationError="required"
control="email"
>Email is required</div>
<div
class="o-input-error l-form-error"
eValidationError="email"
control="email"
>Email is invalid</div>
</div>
因此,我尝试使用以下示例: https://github.com/agiratech/angular4-reactive-form-exercise2/
但是,当我实施它并提交我的表单时,屏幕上的任何地方都没有显示任何错误。您将在下面找到我能想到的所有相关代码。我正在寻找如何让错误显示在屏幕上。我是 Angular 4 的新手,如有任何帮助,我们将不胜感激。
pages.module.ts
import ...
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import ...
import { RegisterComponent } from './register/register.component';
import ...
import { ErrorsComponent } from '../errors.component';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(PagesRoutes),
FormsModule,
ReactiveFormsModule
],
declarations: [
LoginComponent,
RegisterComponent,
LockComponent,
ErrorsComponent
]
})
export class PagesModule {}
register.component.ts
import ...
import {FormGroup, FormBuilder, Validators, FormControl, NgForm} from '@angular/forms';
import ...
import { CustomValidators } from "../../validators/custom-validator.directive";
declare var $:any;
@Component({
moduleId:module.id,
selector: 'register-cmp',
templateUrl: './register.component.html'
})
export class RegisterComponent implements OnInit{
registerForm: FormGroup;
test : Date = new Date();
loading = false;
error = '';
constructor(
private form: FormBuilder,
private router: Router,
private authenticationService: AuthenticationService)
{
this.registerForm = new FormGroup ({
'username':new FormControl('', Validators.required),
'email': new FormControl('', [Validators.required, CustomValidators.validEmail]),
'first_name': new FormControl('', Validators.required),
'last_name': new FormControl('', Validators.required),
'password': new FormControl('', Validators.required),
'confirmPassword': new FormControl('', Validators.required)
});
}
checkFullPageBackgroundImage(){
var $page = $('.full-page');
var image_src = $page.data('image');
if(image_src !== undefined){
var image_container = '<div class="full-page-background" style="background-image: url(' + image_src + ') "/>'
$page.append(image_container);
}
};
ngOnInit() {
this.checkFullPageBackgroundImage();
setTimeout(function(){
// after 1000 ms we add the class animated to the login/register card
$('.card').removeClass('card-hidden');
}, 700)
}
register(registerForm: NgForm) {
console.log(this.registerForm.value);
}
}
register.component.html
<form [formGroup]="registerForm" (ngSubmit)="register(registerForm)">
<div class="card card-plain">
<div class="content">
<div class="form-group">
<input type="text" placeholder="Your First Name" class="form-control" formControlName="first_name">
<errors [control]="registerForm.controls.first_name"></errors>
</div>
<div class="form-group">
<input type="text" placeholder="Your Last Name" class="form-control" formControlName="last_name">
<errors [control]="registerForm.controls.last_name"></errors>
</div>
<div class="form-group">
<input type="text" placeholder="Username" class="form-control" formControlName="username">
<errors [control]="registerForm.controls.username"></errors>
</div>
<div class="form-group">
<input type="email" placeholder="Enter email" class="form-control" formControlName="email">
<errors [control]="registerForm.controls.email"></errors>
</div>
<div class="form-group">
<input type="password" placeholder="Password" class="form-control" formControlName="password">
<errors [control]="registerForm.controls.password"></errors>
</div>
<div class="form-group">
<input type="password" placeholder="Password Confirmation" class="form-control" formControlName="confirmPassword">
<errors [control]="registerForm.controls.confirmPassword"></errors>
</div>
</div>
<div class="footer text-center">
<button [disabled]="loading" type="submit" class="btn btn-fill btn-neutral btn-wd">Create Account</button>
<i *ngIf="loading" class="fa fa-spinner fa-spin fa-fw"></i>
</div>
<errors [control]="registerForm"></errors>
</div>
</form>
errors.component.ts
import { Component, Input } from '@angular/core';
import { AbstractControlDirective, AbstractControl } from '@angular/forms';
@Component({
selector: 'errors',
template: `
<ul *ngIf="showErrors()">
<li class="help-box text-warning" *ngFor="let error of errors()">{{error}}</li>
</ul>
`,
})
export class ErrorsComponent {
private static readonly errorMessages = {
'required': () => 'This field is required',
'minlength': (params) => 'The min number of characters is ' + params.requiredLength,
'maxlength': (params) => 'The max allowed number of characters is ' + params.requiredLength,
'pattern': (params) => 'The required pattern is: ' + params.requiredPattern,
'age': (params) => params.message,
'validEmail': (params) => params.message
};
@Input()
private control: AbstractControlDirective | AbstractControl;
showErrors(): boolean {
return this.control &&
this.control.errors &&
(this.control.dirty || this.control.touched);
}
errors(): string[] {
return Object.keys(this.control.errors)
.map(field => this.getMessage(field, this.control.errors[field]));
}
private getMessage(type: string, params: any) {
return ErrorsComponent.errorMessages[type](params);
}
}
你的例子似乎是基于我在 StackBlitz 中用它做的例子工作的,但是如果你看 errors.component.ts
你会看到它说 this.control.dirty || this.control.touched
,这意味着您需要聚焦然后使用光标模糊输入,或者输入一个值然后退格删除它以进行所需的验证显示。
这是来自 docs and if you click them you can read up on their meaning. So for example dirty 的 FormControl
个属性的列表:
感动
get touched: boolean
A control is marked touched once the user has triggered a blur event on it.
脏
get dirty: boolean
A control is dirty if the user has changed the value in the UI.
Note that programmatic changes to a control's value will not mark it dirty.
此外,通过查看您的代码,我建议您阅读 Angular 风格指南,并继续阅读 FormBuilder
。在我制作的 StackBlitz 示例中,我将您的 FormGroup
示例切换为使用更简洁的 FormBuilder
。最后,看起来您正在使用 jQuery 到 add/remove 类,但请查看 ngClass。在Angular中不需要jQuery,没有它你也可以做任何你想做的事情。
你可以试试这样的-
内部组件 (.ts) 文件 -
public loginForm: FormGroup = this.builder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.minLength(8), Validators.required]]
});
内部组件 (.html) 文件 -
<div class="l-form-row l-login-form__field-row">
<label
class="o-label l-form-label"
for="email"
>Enter your email</label>
<div class="o-input-container">
<input
class="o-input"
type="text"
name="email"
id="email"
formControlName="email"
placeholder="Email"
><div class="o-input-icon"></div>
</div>
<div
class="o-input-error l-form-error"
eValidationError="required"
control="email"
>Email is required</div>
<div
class="o-input-error l-form-error"
eValidationError="email"
control="email"
>Email is invalid</div>
</div>