angular - 具有多个子步骤的角步进器
问题描述
具有多个子步骤的角度步进器。
<mat-step label="Step 1">
////substeps- not in angular material stepper feature
<mat-sub-step><comp1></comp1></mat-sub-step>
<mat-sub-step><comp2></comp2></mat-sub-step>
<mat-sub-step><comp3></comp3></mat-sub-step>
</mat-step>
<mat-step label="Step 2">
////substeps- not in angular material stepper feature
<mat-sub-step><comp4></comp4></mat-sub-step>
<mat-sub-step><comp5></comp5></mat-sub-step>
</mat-step>
因此,对于第 1 步,用户需要填写 3 页,而对于第 2 步,用户需要填写 2 页表单。
但我找不到任何示例或文档来做到这一点。角度步进器没有类似子步骤的东西。
在几乎所有示例中,它们都是一步加载一页。但我需要为每个步骤完成多个组件/页面
解决方案
https://dzone.com/articles/implementing-guard-in-angular-5-app
经过测试
在 hello-angular-practice 的 my-form 页面中练习表单验证:
1) 使用以下命令创建一个 my-form 组件
ng g component MyForm
2)导入my-form,然后在app-routing.module.ts的Routes中添加my-form
import {MyFormComponent} from './my-form/my-form.component';
{path:'my-form', component:MyFormComponent}
3) 将 my-form 路由器链接添加到 app.component.html
<li class="nav-item">
<a class="nav-link" routerLink="/my-form">My Form</a>
</li>
4) 将以下 html 添加到 my-form.component.html
<div class="container">
<div class="jumbotron" style="width:50%;" >
<h2>Form with Validations</h2>
<form (ngSubmit)="submitForm()" [formGroup]="complexForm">
<div class="form-group">
<label>First Name:</label>
<input id="firstName" class="form-control" type="text" placeholder="John" formControlName="firstName">
<div *ngIf="firstName.errors?.required && firstName.touched" class="alert alert-danger">You must include a first
name.</div>
<div *ngIf="firstName.errors?.hasPunctuation" class="alert alert-danger">Name must not have ! or $ characters.</div>
</div>
<div class="form-group">
<label>Last Name</label>
<input id="lastName" class="form-control" type="text" placeholder="Doe" formControlName="lastName">
<div *ngIf="lastName.errors?.required && lastName.touched" class="alert alert-danger">You must include a last
name.</div>
<div *ngIf="lastName.errors?.minlength && lastName.touched" class="alert alert-danger">Your last name must be at
least 5 characters long.</div>
<div *ngIf="lastName.errors?.maxlength && lastName.touched" class="alert alert-danger">Your last name cannot
exceed 10 characters.</div>
</div>
<div class="form-group">
<label>Gender</label>
<div class="alert alert-danger" *ngIf="!gender.valid && gender.touched">You must select a gender.</div>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" value="Male" formControlName="gender">
Male
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" value="Female" formControlName="gender">
Female
</label>
</div>
<div class="form-group">
<fieldset formGroupName="activities">
<div class="form-group">
<label>Activities</label>
</div>
<label class="checkbox-inline">
<input type="checkbox" value="hiking" name="hiking" formControlName="hiking"> Hiking
</label>
<label class="checkbox-inline">
<input type="checkbox" value="swimming" name="swimming" formControlName="swimming"> Swimming
</label>
<label class="checkbox-inline">
<input type="checkbox" value="running" name="running" formControlName="running"> Running
</label>
</fieldset>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary" [disabled]="!complexForm.valid">Submit</button>
</div>
</form>
</div>
</div>
5) 将以下 css 添加到 my-form.component.css
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
6)将以下导入添加到 my-form.component.ts
import { FormGroup, FormBuilder, Validators, FormControl, ValidatorFn, ValidationErrors, AbstractControl } from '@angular/forms';
import { Observable } from 'rxjs';
6) 将 formBuilder 注入 my-form.component.ts 的构造函数
constructor(private fb: FormBuilder){
}
7) 然后在 my-form.component.ts 中添加以下所有代码
complexForm = this.fb.group({
'firstName' : new FormControl('', [Validators.required,this.hasPunctuation("!"),this.hasPunctuation("$")]),
'lastName': new FormControl('', Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(10)])),
'gender' : new FormControl(null, Validators.required),
'activities': this.fb.group({
'hiking' : [false],
'running' : [false],
'swimming' : [false]
})
});
get firstName() {return this.complexForm.get('firstName')}
get lastName() {return this.complexForm.get('lastName')}
get gender() {return this.complexForm.get('gender')}
get activities() {return this.complexForm.get('activities')}
hasPunctuation(punctuation: string): ValidatorFn{
return (control:AbstractControl): {[key: string]: any} | null => {
return control.value.indexOf(punctuation) >= 0 ?
{hasPunctuation: true }: null;
}
}
submitForm(){
console.log(this.complexForm.value);
console.log("hiking? "+this.complexForm.get('activities').get('hiking').value);
console.log("swimming? "+this.complexForm.get('activities').get('swimming').value);
console.log("running? "+this.complexForm.get('activities').get('running').value);
}
在 hello-angular-practice 中练习角管:
1) 要在 bio-component.html 中显示所有开发人员的名字,请更新 dev.firstName,如下所示:
<h3><a [routerLink]="['/bio',dev.id]">{{dev.firstName | uppercase}}</a></h3>
练习后卫:
1)创建一个身份验证守卫
ng generate guard auth
2) 生成登录组件并进行设置
ng g component login
3) 将 login.component.ts 添加到路由
import { LoginComponent } from './login/login.component';
{path:'login', component:LoginComponent}
4)将登录路由器链接添加到app.component.html
<li class="nav-item">
<a class="nav-link" routerLink="/login">Login</a>
</li>
5)使用以下html创建一个登录页面
<div class="container">
<h1>Login</h1>
<div class="row">
<div class="col-md-6">
<form (ngSubmit)="login()" [formGroup]="loginForm" >
<div class="form-group">
<label for="email">Email</label>
<input type="email" placeholder="Email" class="form-control" formControlName="email">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" placeholder="Password" class="form-control" formControlName="password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Login</button>
</div>
</form>
</div>
</div>
6)创建身份验证服务
ng g service AuthService
7)更新auth.service如下
一)进口
import { Router } from '@angular/router';
b) 注入路由器
constructor(private myRoute: Router) { }
c) 添加以下 fi=unction
sendToken(token: string) {
localStorage.setItem("LoggedInUser", token)
}
getToken() {
return localStorage.getItem("LoggedInUser")
}
isLoggednIn() {
return this.getToken() !== null;
}
logout() {
localStorage.removeItem("LoggedInUser");
this.myRoute.navigate(["login"]);
}
8) 现在是时候编辑我们的 login.component.ts 文件了。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthServiceService } from '../auth-service.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
loginForm;
constructor(private fb: FormBuilder,
private myRoute: Router,
private auth: AuthServiceService) {
this.loginForm = fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', Validators.required]
});
}
ngOnInit() {
}
login() {
if (this.loginForm.valid) {
this.auth.sendToken(this.loginForm.value.email)
this.myRoute.navigate([""]);
}
}
9) 更新认证守卫
一)进口
import { AuthServiceService } from './auth-service.service';
import {Router} from '@angular/router';
b) 更新构造函数
constructor(private auth: AuthServiceService,private myRoute: Router){}
c) 更新 canActivate
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(this.auth.isLoggednIn()){
return true;
}else{
this.myRoute.navigate(["login"]);
return false;
}
}
10) 不要忘记在 app.module.ts 中添加 AuthService 和 AuthGuard 作为提供者。
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
AppRoutingModule,
HttpClientModule,
AuthGuard
],
11) 在路由中使用 Auth Guard
const routes: Routes =[
{path:'', component: HomeComponent,canActivate: [AuthGuard]},
{path:'bio', component: BioComponent,canActivate: [AuthGuard]},
{path:'bio/:id', component: BioDetailsComponent},
{path:'create-bio', component:BioCreateComponent,canActivate: [AuthGuard]},
{path:'my-form', component:MyFormComponent,canActivate: [AuthGuard]},
{path:'login', component:LoginComponent},
];
12)添加app.component.ts
import { AuthService } from '../auth.service';
constructor(private auth: AuthService) { }
13) 更新 app.component.html 中的导航
<nav class="navbar navbar-expand-sm bg-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" *ngIf="auth.isLoggednIn()" routerLink="">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="auth.isLoggednIn()" routerLink="/bio">My Bio</a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="auth.isLoggednIn()" routerLink="/create-bio">Create Bio</a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="auth.isLoggednIn()" routerLink="/my-form">My Form</a>
</li>
<li class="nav-item">
<a class="nav-link" *ngIf="!auth.isLoggednIn()" routerLink="/login">Login</a>
</li>
</ul>
</nav>
<router-outlet></router-outlet>
推荐阅读
- tensorflow - 关于迭代数据集的Tensorflow速成课程问题
- r - Data.table 中的多个灵活的逻辑列比较
- c# - 按钮在设置为非活动和重新激活后无响应
- c - 带有 .c 和 .cpp 文件的 R 包,带有 Rcpp
- docusignapi - Docusign - 设置收件人语言 - 收件人收到的电子邮件始终为英文
- javascript - 无法调用其类型缺少调用签名的表达式。类型没有兼容的调用签名 2349
- html - 为什么后一个块元素的盒子从前一个块元素的内容开始,而不是从前一个元素的边框开始?
- javascript - 使用 ES6 在嵌套循环中返回父匹配
- android - 使用架构组件导航的 android 的 XML 材质转换
- emacs - 我可以在没有更多字母的情况下在 emacs 中选择它吗?