Angular routing official website
1. Get started quickly
- Routing is based on modules, and each module can have its own route. Each route corresponds to a component.
- In the module, we need to introduce
RouterModule
the module,RouterModule
which provides us with the routing function. And you need to introduce and declare the components that need to be displayed
...
import {
RouterModule} from "@angular/router";
import {
HomeComponent } from './pages/home/home.component';
import {
AboutComponent } from './pages/about/about.component';
@NgModule({
// 声明当前模块拥有哪些组件
declarations: [
AppComponent, // 根组件
HomeComponent,
AboutComponent,
],
...
})
- Define routing rules and declare that the current module depends on the routing module; at the same time, the routing rules must be passed to the routing module
RouterModule.forRoot
This method is used to define routes. This method ensures that the application will only instantiate oneRouterModule
. The first parameter is an object array. The object usually consists of two attributes,path
representing the address bar path andcomponent
components that are dynamically loaded according to the path; the second parameter is Configuration object,useHash:true
indicating the usehash
of routing instead ofhistory
routing
...
// path开头不需要加斜线
const routes = [
{
path: 'home', component: HomeComponent},
{
path: 'about', component: AboutComponent},
];
...
@NgModule({
...
imports: [BrowserModule, RouterModule.forRoot(routes, {
useHash: true})],
...
})
- Define routing jump links (slashes must be added) and routing sockets (placeholders) in the module root component.
routerLink
is aAngular
built-in directive that connects the routes you define to the template file.
<a routerLink="/home">首页</a> |
<a routerLink="/about">关于</a>
<router-outlet></router-outlet>
- Clicking on these two
a
links,url
the content rendered by the address and the location of the routing socket will change accordingly.
2. Matching rules
(1) Redirect
home
Redirect to route when there is no route address in the address bar- By default,
Angular
when matching routing rules, the prefix is matched.path
If it is empty, it will match routing connections with the prefix '/', so it must be added topathMatch:'full'
indicate that the routing rules completely match.
const routes:Routes = [
{
path: 'home', component: HomeComponent},
{
path: 'about', component: AboutComponent},
{
path: '', redirectTo: 'home', pathMatch: 'full'}
];
(2) 404 page
- Routing rules are matched from top to bottom. When all routes are not matched, a 404 page needs to be displayed.
**
It is a wildcard character and will match all routes, so it should be placed at the end of the array.
const routes:Routes = [
{
path: 'home', component: HomeComponent},
{
path: 'about', component: AboutComponent},
{
path: '', redirectTo: 'home', pathMatch: 'full'},
{
path: '**', component: NotFoundComponent}
];
3. Routing parameters
(1) Query parameters
[queryParams]
Query parameters use dynamic binding when defining routing connections
<a routerLink="/about" [queryParams]="{name:'zs'}">关于</a>
- When the corresponding component is dynamically rendered, the passed parameters can be obtained inside the component.
ActivatedRoute
Used to access routing information corresponding to dynamically loaded componentsroute.queryParamMap
Is anObservable
object that saves query parameter information;get
you can get the corresponding value by using the method
import {
ActivatedRoute} from '@angular/router';
export class AboutComponent {
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.queryParamMap.subscribe(query => {
console.log(query.get('name'));
})
}
}
(2) Dynamic parameters
path
Dynamic parameters need to reserve parameter positions in the attributes of routing rules.
{
path: 'about/:name/:age', component: AboutComponent},
- The component template
routerLink
needs to bind a dynamic array and pass the path and parameter list in sequence.
<a [routerLink]="['/about','zhangsan',78]">关于</a>
- In the object component, obtain dynamic parameter information through
ActivatedRoute
the instance objectparamMap
4. Sub-level routing
When defining a route, children
you can define sub-level routes through the attributes of the route.
{
path: 'about',
component: AboutComponent,
children: [
{
path: 'company', component: CompanyComponent},
{
path: 'industry', component: IndustryComponent},
]
},
In the parent page AboutComponent
, define the jump link of the child route and define the routing socket for the child route
<a routerLink="/about/company">公司</a>
<a routerLink="/about/industry">行业</a>
<router-outlet></router-outlet>
5. Navigation routing
Navigation routing can realize page jump to the path of non-child routing.
<button (click)="goHome()">点击跳转到首页</button>
// 需要引入Router模块
constructor(private router: Router) {
}
goHome() {
// 查询参数
this.router.navigate(['/home'],{
queryParams: {
name: 'zhangsan'
}
})
// 动态参数
// this.router.navigate(['/home','zhangsan'])
}
6. Routing module
Extract the code related to defining routing and put it in a separate module for management.
- Define a module under the root path
ng g m route --flat=true
.--flat=true
The folder will not be created, butsrc/app
the relevant files will be created directly under the current project. The default value isfalse
- Put the code that defines routing rules into the module class
- Define the route in the module class and export it
RouterModule
imports: [
CommonModule,
RouterModule.forRoot(routes, {
useHash: true})
],
exports: [RouterModule]
- Import the defined routing module in AppModule
imports: [BrowserModule,RouteModule],
7. Lazy loading of routing module
Lazy loading of the routing module allows the user to request only the root module when requesting the application for the first time, and other modules will be loaded when the user accesses the application, optimizing the user experience.
- Create a lazy-loaded module; use it while creating the module
--routing=true
. Thisangular-cli
will directly help us create the routing module of the module.
ng g m sports --routing=true
- Create the root component of the module
ng g c sports
- Define routing in
sports
the routing module; define routing in the feature module and use itRouterModule.forChild
. Only one routing configuration array can be accepted as a parameter.
import {
SportsComponent} from "./sports.component";
const routes: Routes = [
{
path: '', component: SportsComponent},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
- Define the loading rules for this feature module in the routing rules of the root routing module.
When the routing address is/sport
, dynamically loadsport
the module
{
path: 'sports', loadChildren: () => import('./sports/sports.module').then(m => m.SportsModule)},
- Define jump links in the root component template
<a routerLink="/sports">运动界面</a>
It can be seen from the console sources
that when the button of the sports interface is clicked, sports
the module will be loaded dynamically.
8. Route guard
The route guard will tell the route whether navigation to the requested route is allowed.
The return value of the route guard has four situations:
- Boolean value:
true
indicates that it can be activated,false
indicates that it cannot be activated UrlTree
: represents aUrl
tree that can be redirected to a newUrl
- Can return async
Promise<boolean | UrlTree>
: represents a promise, which can be parsed as a boolean orUrl
tree - Can return
Observable<boolean | UrlTree>
: represents an observable object, which can be parsed as a boolean orUrl
a tree
(1)CanActivate
CanActivate
It is an interface. We need to customize a routing guard class, and the routing guard class must implement this interface. This interface stipulates that the class must have canActivate
a method to determine whether to allow access to the route. A route can apply multiple guards. Only when all guards are allowed, the route can be accessed.
- Create a route guard class and place the route guard method
ng g guard guards/authGuard
Angular-cli
Some basic code will be created for us. IncanActivate
the method, we return directlyfalse
, indicating that access to the target route is not allowed.
import {
Injectable} from '@angular/core';
import {
ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree} from '@angular/router';
import {
Observable} from 'rxjs';
// 被Injectable修饰,说明路由守卫类是一个服务类
@Injectable({
providedIn: 'root'
})
// AuthGuardGuard:路由守卫类
export class AuthGuardGuard implements CanActivate {
// canActivate:路由守卫方法
// 参数:
// route:ActivatedRouteSnapshot:路由快照,包含与当前组件相关的路由的当前瞬间信息。
// state:RouterStateSnapshot:路由状态快照,表示路由器在当前瞬间的状态
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return false;
}
}
- Apply the route guard to the corresponding route in the routing rules
{
path: 'user',
loadChildren: () => import('./user/user.module').then(m => m.UserModule),
canActivate: [AuthGuardGuard]
},
(2) CanActivateChild
Check whether the child routes of a certain route can be accessed
- Create a routing guard class
ng g guard about/about
and selectCanActivateChild
canActivateChild
Change the return value of the method tofalse
- Apply this guard to the corresponding route, so that the
about
two sub-routes of the route can be disabled.
{
path: 'about',
component: AboutComponent,
children: [
{
path: 'company', component: CompanyComponent},
{
path: 'industry', component: IndustryComponent}
],
canActivateChild: [AboutGuard]
},
- Clicking these two jump links will not cause the page to jump.
(三)CanDeactivate
Detecting whether the user can leave the current route can be used in scenarios where the user fills in the form items and leaves before saving.
Whether the route can leave should depend on the component where the route guard is currently applied. The component class that uses this route guard should define a method with the same name to tell the route guard whether it can leave the current page. This method is called in the route guard to determine what the return value is.
- Create route guard class
ng g guard unsave/unsave
- In the route guard class, define an interface to specify the type of judgment function that needs to be defined in the component applied to the route guard. In
canDeactivate
the method, the return value is determined based on the component's judgment function; returningtrue
means that leaving the current route is allowed, and returningfalse
means that leaving is not allowed.
export interface CanLeave {
canLeave: () => boolean;
}
export class UnsaveGuard implements CanDeactivate<unknown> {
canDeactivate(
component: unknown,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
// @ts-ignore
if (component.canLeave()) {
return true;
} else {
if(confirm("是否离开当前页面?")){
return true;
}else{
return false;
}
}
}
}
- Add the route guard to the corresponding route where the route is defined.
{
path: 'home/:username',
component: HomeComponent,
canDeactivate: [UnsaveGuard]
},
- In
HomeComponent
the component class, you need to implementCanLeave
the interface and definecanleave
a method to return aboolean
value to tell the routing guard whether the current route can leave.
export class HomeComponent implements CanLeave{
canLeave(): boolean {
return false;
}
}
- A pop-up window will pop up when you leave the homepage. Click OK to leave, and click Unblock route jump.
(4) Resolve
Perform an asynchronous operation to obtain data before jumping to the route, and perform the route jump after the asynchronous operation is completed.
- Create
Resolve
a routing guard classng g resolver resolvers/username
. The Resolve class is also a service class. resolve
Return one in the methodPromise
, obtain and return the required data asynchronously
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<String> {
return new Promise<String>((resolve, reject) => {
setTimeout(() => {
resolve("张三");
}, 2000);
})
}
resolve
Apply this routing guard to the corresponding route and add an attribute to the routing rule definition . This attribute is an array, whichkey
is an attribute added to the component andvalue
points to the route guard that obtains the corresponding data.
{
path: 'home/:username',
component: HomeComponent,
resolve: {
username: UsernameResolver
}
},
- In the component,
this.route.snapshot.data
you can obtain the data passed by the routing guard through attributes.
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
console.log(this.route.snapshot.data['username'])
}
- Click the button to jump to the home page. The jump occurs after two seconds and the console output