步骤
1、新建模型类RegisterUser
CitiesAngularApp下打开终端,执行如下命令
ng g class models\RegisterUser
得到register-user.ts,更新后如下
export class RegisterUser {
personName: string | null = null;
email: string | null = null;
phone: string | null = null;
password: string | null = null;
confirmPassword: string | null = null;
}
2、新建Service
CitiesAngularApp下打开终端,执行如下命令
ng g service services\Account
得到account.service.ts,更新后如下
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { RegisterUser } from '../models/register-user';
const API_BASE_URL: string = "https://localhost:7173/api/v1/account/";
@Injectable({
providedIn: 'root'
})
export class AccountService {
constructor(private httpClient: HttpClient) {
}
public postRegister(registerUser: RegisterUser): Observable<RegisterUser> {
return this.httpClient.post<RegisterUser>(`${API_BASE_URL}register`, registerUser);
}
}
3、新建Component
CitiesAngularApp下打开终端,执行如下命令
ng g component Register
得到register.component.ts,更新后如下
import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { RegisterUser } from '../models/register-user';
import { AccountService } from '../services/account.service';
import { CompareValidation } from '../validators/custom-validators';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent {
registerForm: FormGroup;
isRegisterFormSubmitted: boolean = false;
constructor(private accountService: AccountService, private router: Router) {
this.registerForm = new FormGroup({
personName: new FormControl(null, [Validators.required]),
email: new FormControl(null, [Validators.required, Validators.email]),
phoneNumber: new FormControl(null, [Validators.required]),
password: new FormControl(null, [Validators.required]),
confirmPassword: new FormControl(null, [Validators.required])
},
{
validators: [CompareValidation("password", "confirmPassword")]
});
}
get register_personNameControl(): any {
return this.registerForm.controls["personName"];
}
get register_emailControl(): any {
return this.registerForm.controls["email"];
}
get register_phoneNumberControl(): any {
return this.registerForm.controls["phoneNumber"];
}
get register_passwordControl(): any {
return this.registerForm.controls["password"];
}
get register_confirmPasswordControl(): any {
return this.registerForm.controls["confirmPassword"];
}
registerSubmitted() {
this.isRegisterFormSubmitted = true;
if (this.registerForm.valid) {
this.accountService.postRegister(this.registerForm.value).subscribe({
next: (response: RegisterUser) => {
console.log(response);
this.isRegisterFormSubmitted = false;
this.router.navigate(['/cities']);
this.registerForm.reset();
},
error: (error) => {
console.log(error);
},
complete: () => { },
});
}
}
}
4、register.component.html
<div class="w-75 margin-auto">
<div class="form-container">
<h2>Register</h2>
<form [formGroup]="registerForm" (ngSubmit)="registerSubmitted()">
<!-- personName -->
<div class="form-field flex">
<div class="w-25">
<label for="personName" class="form-label pt">Person Name</label>
</div>
<div class="flex-1">
<input type="text" id="personName" class="form-input" formControlName="personName" />
<span class="text-red" *ngIf="(register_personNameControl.touched || isRegisterFormSubmitted) && (register_personNameControl.errors?.['required'])">Person Name can't be blank</span>
</div>
</div>
<!-- email -->
<div class="form-field flex">
<div class="w-25">
<label for="email" class="form-label pt">Email</label>
</div>
<div class="flex-1">
<input type="text" id="email" class="form-input" formControlName="email" />
<span class="text-red" *ngIf="(register_emailControl.touched || isRegisterFormSubmitted) && (register_emailControl.errors?.['required'])">Email can't be blank</span>
<span class="text-red" *ngIf="(register_emailControl.touched || isRegisterFormSubmitted) && (register_emailControl.errors?.['email'])">Email should be in a proper email address format</span>
</div>
</div>
<!-- phoneNumber -->
<div class="form-field flex">
<div class="w-25">
<label for="phoneNumber" class="form-label pt">Phone Number</label>
</div>
<div class="flex-1">
<input type="text" id="phoneNumber" class="form-input" formControlName="phoneNumber" />
<span class="text-red" *ngIf="(register_phoneNumberControl.touched || isRegisterFormSubmitted) && (register_phoneNumberControl.errors?.['required'])">Phone number can't be blank</span>
</div>
</div>
<!-- password -->
<div class="form-field flex">
<div class="w-25">
<label for="password" class="form-label pt">Password</label>
</div>
<div class="flex-1">
<input type="password" id="password" class="form-input" formControlName="password" />
<span class="text-red" *ngIf="(register_passwordControl.touched || isRegisterFormSubmitted) && (register_passwordControl.errors?.['required'])">Password can't be blank</span>
</div>
</div>
<!-- confirmPassword -->
<div class="form-field flex">
<div class="w-25">
<label for="confirmPassword" class="form-label pt">Confirm Password</label>
</div>
<div class="flex-1">
<input type="password" id="confirmPassword" class="form-input" formControlName="confirmPassword" />
<span class="text-red" *ngIf="(register_confirmPasswordControl.touched || isRegisterFormSubmitted) && (register_confirmPasswordControl.errors?.['required'])">Confirm Password can't be blank</span>
<span class="text-red" *ngIf="(register_confirmPasswordControl.touched || isRegisterFormSubmitted) && (register_confirmPasswordControl.errors?.['compareValidator'])">Password and confirm password do not match</span>
</div>
</div>
<!-- submit -->
<div class="form-field flex">
<div class="w-25">
</div>
<div class="flex-1">
<button type="submit" class="button button-green-back">Register</button>
</div>
</div>
</form>
</div>
</div>
5、app.component.html添加Register
<div class="container">
<div class="page-content">
<div class="margin-bottom">
<div class="flex">
<div class="flex-1" id="top-bar-div">
<h2 class="app-title">
Cities Manager
</h2>
</div>
<div class="flex-1" id="search-box-div">
<div class="navbar account-links">
<ul>
<li>
<a [routerLink]="[ '/login' ]">Login</a>
<!--<a routerLink="/login">Login</a>-->
</li>
<li>
<a [routerLink]="[ '/register' ]">Register</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="navbar mb">
<ul>
<li>
<a [routerLink]="[ '/cities']" [routerLinkActive]="[ 'nav-active']">Cities</a>
<!--<a routerLink="/cities" routerLinkActive="active">Cities</a>-->
</li>
</ul>
</div>
<div class="body">
<router-outlet></router-outlet>
</div>
</div>
</div>
6、app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CitiesComponent } from './cities/cities.component';
import { RegisterComponent } from './register/register.component';
const routes: Routes = [
{ path: "cities", component: CitiesComponent },
{ path: "register", component: RegisterComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
7、Add-Migration/Update-DataBase生成AspNet开头的表
8、custom-validators.ts
app文件夹下新建文件夹validators,添加custom-validators.ts
import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms";
export function CompareValidation(controlToValidate: string, controlToCompare: string): ValidatorFn {
return (formGroupAsControl: AbstractControl): ValidationErrors | null => {
const formGroup = formGroupAsControl as FormGroup;
const control = formGroup.controls[controlToValidate];
const matchingControl = formGroup.controls[controlToCompare];
if (control.value != matchingControl.value) {
formGroup.get(controlToCompare)?.setErrors({ compareValidator: { valid: false } });
return { compareValidator: true }
}
else
return null;
}
}
结果
程序运行后,可以注册用户。
Gitee获取源码: