In Angular, routing以模块为单位
, and each module can have its own routing. [Related tutorial recommendation: "angular tutorial"]
1. Create page components, Layout components and Navigation components for routing use
Create the home page component ng gc pages/home
Create the about us page component ng gc pages/about
Create the layout component ng gc pages/layout
Create the navigation component ng gc pages/navigation
2. Create routing rules
// app.module.ts import { Routes } from "@angular/router" const routes: Routes = [ { path: "home", component:HomeComponent }, { path: "about", component: AboutComponent } ]
3. Introduce the routing module and start
// app.module.ts import { RouterModule, Routes } from "@angular/router" @NgModule({ imports: [RouterModule.forRoot(routes, { useHash: true })], }) export class AppModule {}
4. Add路由插座
<!-- The routing socket, that is, the routing component matched to the placeholder component will be displayed here --> <router-outlet></router-outlet>5. Define the link
<a routerLink="/home">Homepage</a>
in the navigation component
<a routerLink="/about">About Us</a>
1. Redirect
const routes: Routes = [ { path: "home", component:HomeComponent }, { path: "about", component: AboutComponent }, { path: "", // Redirect redirectTo: "home", //Exact match pathMatch: "full" } ]
2. 404 page
const routes: Routes = [ { path: "home", component:HomeComponent }, { path: "about", component: AboutComponent }, { path: "**", component: NotFoundComponent } ]
1. Query parameters
<a routerLink="/about" [queryParams]="{ name: 'kitty' }">About us</a>
import { ActivatedRoute } from "@angular/router" export class AboutComponent implements OnInit { constructor(private route: ActivatedRoute) {} ngOnInit(): void { this.route.queryParamMap.subscribe(query => { query.get("name") }) } }
2. Dynamic parameter
const routes: Routes = [ { path: "home", component:HomeComponent }, { path: "about/:name", component: AboutComponent } ]
<a [routerLink]="['/about', 'zhangsan']">About us</a>
import { ActivatedRoute } from "@angular/router" export class AboutComponent implements OnInit { constructor(private route: ActivatedRoute) {} ngOnInit(): void { this.route.paramMap.subscribe(params => { params.get("name") }) } }
Route nesting refers to how to定义子级路由
.
const routes: Routes = [ { path: "about", component: AboutComponent, children: [ { path: "introduce", component: IntroduceComponent }, { path: "history", component: HistoryComponent } ] } ]
<!-- about.component.html --> <app-layout> <p>about works!</p> <a routerLink="/about/introduce">Company Profile</a> <a routerLink="/about/history">Development History</a> <div> <router-outlet></router-outlet> </div> </app-layout>
Name the socket
Expose child routing components into different routing outlets.
{ path: "about", component: AboutComponent, children: [ { path: "introduce", component: IntroduceComponent, outlet: "left" }, { path: "history", component: HistoryComponent, outlet: "right" } ] }
<!-- about.component.html --> <app-layout> <p>about works!</p> <router-outlet name="left"></router-outlet> <router-outlet name="right"></router-outlet> </app-layout>
<a [routerLink]="[ '/about', { outlets: { left: ['introduce'], right: ['history'] } } ]" >About us</a>
<!-- app.component.html --> <button (click)="jump()">Jump to development history</button>
// app.component.ts import { Router } from "@angular/router" export class HomeComponent { constructor(private router: Router) {} jump() { this.router.navigate(["/about/history"], { queryParams: { name: "Kitty" } }) } }
Abstract the routing configuration in the root module into a separate routing module, called根路由模块
, and then introduce the root routing module into the root module.
import { NgModule } from "@angular/core" import { HomeComponent } from "./pages/home/home.component" import { NotFoundComponent } from "./pages/not-found/not-found.component" const routes: Routes = [ { path: "", component:HomeComponent }, { path: "**", component: NotFoundComponent } ] @NgModule({ declarations: [], imports: [RouterModule.forRoot(routes, { useHash: true })], // Export the Angular routing function module, because the routing socket component provided in the RouterModule module is used in the root component of the root module exports: [RouterModule] }) export class AppRoutingModule {}
import { BrowserModule } from "@angular/platform-browser" import { NgModule } from "@angular/core" import {AppComponent} from "./app.component" import { AppRoutingModule } from "./app-routing.module" import { HomeComponent } from "./pages/home/home.component" import { NotFoundComponent } from "./pages/not-found/not-found.component" @NgModule({ declarations: [AppComponent, HomeComponent, NotFoundComponent], imports: [BrowserModule, AppRoutingModule], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
Lazy loading of routes is based on模块
.
1. Create the user module ng gm user --routing=true
and create the routing module of this module together.
2. Create the login page component ng gc user/pages/login
3. Create the registration page component ng gc user/pages/register
4. Configuration Routing rules for user modules
import { NgModule } from "@angular/core" import { Routes, RouterModule } from "@angular/router" import { LoginComponent } from "./pages/login/login.component" import { RegisterComponent } from "./pages/register/register.component" const routes: Routes = [ { path: "login", component: LoginComponent }, { path: "register", component: RegisterComponent } ] @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class UserRoutingModule {}
5. Associate the user routing module to the main routing module
// app-routing.module.ts const routes: Routes = [ { path: "user", loadChildren: () => import("./user/user.module").then(m => m.UserModule) } ]6. Add the access link
<a routerLink="/user/login">Login</a>
in the navigation component
<a routerLink="/user/register">Register</a>
The route guard tells the route whether navigation to the requested route is allowed.
Route guard methods can return boolean
or Observable <boolean>
or Promise <boolean>
, which resolve to a Boolean value at some point in the future.
1. CanActivate
checks是否可以访问某一个路由
.
CanActivate为接口
, and the route guard class must implement this interface. This interface stipulates that the class needs to have a canActivate method, which determines whether to allow access to the target route.
A route can apply多个守卫
. If all guard methods are allowed, the route is allowed to be accessed. If one guard method is not allowed, the route is not allowed to be accessed.
Create route guards: ng g guard guards/auth
import { Injectable } from "@angular/core" import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from "@angular/router" import { Observable } from "rxjs" @Injectable({ providedIn: "root" }) export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate(): boolean | UrlTree { // Used to implement jump return this.router.createUrlTree(["/user/login"]) // Disable access to the target route return false //Allow access to target route return true } }
{ path: "about", component: AboutComponent, canActivate: [AuthGuard] }
2. CanActivateChild
checks whether the user can access a certain sub-route.
Create a route guard: ng g guard guards/admin
Note: To select CanActivateChild, move the arrow to this option and tap space to confirm the selection.
import { Injectable } from "@angular/core" import { CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from "@angular/router" import { Observable } from "rxjs" @Injectable({ providedIn: "root" }) export class AdminGuard implements CanActivateChild { canActivateChild(): boolean | UrlTree { return true } }
{ path: "about", component: AboutComponent, canActivateChild: [AdminGuard], children: [ { path: "introduce", component: IntroduceComponent } ] }
3. CanDeactivate
checks whether the user can exit the route.
For example, if the content entered by the user in the form is not saved and the user wants to leave the route, the guard can be called to prompt the user.
import { Injectable } from "@angular/core" import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from "@angular/router" import { Observable } from "rxjs" export interface CanComponentLeave { canLeave: () => boolean } @Injectable({ providedIn: "root" }) export class UnsaveGuard implements CanDeactivate<CanComponentLeave> { canDeactivate(component: CanComponentLeave): boolean { if (component.canLeave()) { return true } return false } }
{ path: "", component: HomeComponent, canDeactivate: [UnsaveGuard] }
import { CanComponentLeave } from "src/app/guards/unsave.guard" export class HomeComponent implements CanComponentLeave { myForm: FormGroup = new FormGroup({ username: new FormControl() }) canLeave(): boolean { if (this.myForm.dirty) { if (window.confirm("There is data that has not been saved, are you sure you want to leave?")) { return true } else { return false } } return true }
4. Resolve
allows you to obtain data before entering routing, and then enter routing after data acquisition is completed.
ng g resolver <name>
import { Injectable } from "@angular/core" import { Resolve } from "@angular/router" type returnType = Promise<{ name: string }> @Injectable({ providedIn: "root" }) export class ResolveGuard implements Resolve<returnType> { resolve(): returnType { return new Promise(function (resolve) { setTimeout(() => { resolve({ name: "Zhang San" }) }, 2000) }) } }
{ path: "", component: HomeComponent, resolve: { user:ResolveGuard } }
export class HomeComponent { constructor(private route: ActivatedRoute) {} ngOnInit(): void { console.log(this.route.snapshot.data.user) } }