1. Overview
The fifth note in Angular's pit entry, which has been delayed for more than a month because of overtime, focuses on how to configure routing, complete redirection, and pass parameters in Angular."Advanced" features such as routing guards and lazy routing loads will not appear in this article
Corresponding official document address:
Supporting code address: angular-practice/src/router-tutorial
2. Contents
- Angular from pit-digging to pit-digging - Getting started with Angular
- Angular Digging to Digging-Component Consumption Guide
- Angular From Digging to Digging - Overview of Form Controls
- Angular From Digging to Digging - Overview of HTTP Requests
- Angular Routing From Dig to Dig-Router Starter North
3. Knowledge Graph
4. Step by Step
4.1. Basic concepts 4.1.1,base urlIn Angular applications, the framework automatically uses the base url configuration in the index.html file as the base path address for components, templates, and module files.By default, the app folder is the root directory for the entire application, so we can just use the default <base href='/'> in index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>RouterTutorial</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-root></app-root> </body> </html>4.1.2, Routing Configuration
In the Angular project, the routing of the system requires that we map a url address to a displayed component, so the mapping relationship between the url and the component needs to be set manually
Because we chose to add a routing module when we created the project using Angular CLI, we can define the route directly in the app-routing.module.ts file.Eventually, the routing information that we define will be introduced into the entire project in the root module
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './components/home/home.component'; import { PagenotfoundComponent } from './components/pagenotfound/pagenotfound.component'; import { NewsComponent } from './components/news/news.component'; import { ProductComponent } from './components/product/product.component'; // Configure Routing Information const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'news', component: NewsComponent }, { path: 'product', component: ProductComponent }, { path: '**', component: PagenotfoundComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule // Introducing routing configuration information ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
When routing information is defined, we need to use the <router-outlet>tag on the page to tell Angular where to render the page.For jumps between routes, we can use the RouterLink directive on the a tag to bind specific routes to complete address jumps
<div> <a [routerLink]="[ '/news' ]" routerLinkActive="active"> <span>News</span> </a> <a [routerLink]="[ '/product' ]" routerLinkActive="active"> <span>Product</span> </a> </div> <div> <div> <!-- Export for component rendering --> <router-outlet></router-outlet> </div> </div> </div>
Of course, if you have to find something for yourself, you can use the href attribute of tag a to jump, which is also possible, but it will look a little less spicy and smart when it comes to the functionality of the related framework later
4.1.3, redirection and distribution addressesIn general, for the default path after entering the system, we choose to redirect to a specific address. Here, when defining routing information, we define an empty path to represent the default address of the system. When requested by the user, we redirect to the / home path because only the full url is availableThe redirection should only occur if the address matches an empty string, so you need to specify that the matching pattern is all matches
const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' } ];
Angular parses routes in the order in which we define them and terminates them as soon as they match.Therefore, this wildcard routing configuration, similar to the 404 error, should be last defined because each url address can be matched
const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'news', component: NewsComponent }, { path: 'product', component: ProductComponent }, { path: '**', component: PagenotfoundComponent }, ];
As you can see from the screenshot, when we open the system, we automatically jump to the home path we specified, and when we click the menu button, the corresponding component page loads.
4.1.4, Activated RoutesIn many cases, we may add a specific style to prompt the user for the selected route, so when we define router-link, we can use the routerLinkActive property to bind a style class of css, and automatically add the specified style class when the route corresponding to the link is active
4.2. Parameter transfer between routesA common use of routing jumps is when we need to pass certain data as parameters to the next page, such as selecting a row from the list to click on it and jumping to the corresponding details page
There are two common ways to pass parameters
4.2.1, query query parameter deliveryThe most common way to pass parameters is to add parameters and corresponding values after the route address that needs to be jumped, and get the corresponding parameter values by getting the parameter key on the page that needs to be jumped
<a href="www.yoursite.com/product?productId=xxxx">Jump</a>
For routing jumps directly through the a tag, we can add query parameter information on the a tag by binding the queryParams attribute
Here, the queryParams property binds an object, and Angular automatically splices this parameter object with the url for us.For attribute values corresponding to attributes (key) in a parameter object, we can either bind the attributes in a component to assign values dynamically or add single quotation marks to treat the parameter values as fixed values, such as two query parameters in the following code that are fixed values
<a [routerLink]="[ '/news' ]" routerLinkActive="active" [queryParams]="">News</a>
Similarly, we can also complete a route jump in js. For this scenario, we need to inject the Router class through constructor dependency in the component class that makes the JS jump, and then complete the route jump through the navigate method of the Router class. For possible query parameters, we need to define a NavigationExtras Type of variable to set
import { Component, OnInit } from '@angular/core'; // Introducing routing modules import { Router, NavigationExtras } from '@angular/router'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent implements OnInit { constructor(private router: Router) {} ngOnInit(): void {} /** * Passing parameters as query query string using js */ queryNavigate() { // Query parameters let query: NavigationExtras = { queryParams: { category: 'social', date: '2020-05-04' } }; this.router.navigate(['/news' ], query); } }
Now that the parameter information is appended to the jump, we definitely need to get the parameter value passed on the page after the jump.In Angular, you need to rely on injecting ActivatedRoute in the component class to get the passed parameter information
Here queryParamMap is an Observable object, so you need to use the subscribe method to get the passed parameter values
import { Component, OnInit } from '@angular/core'; // Introducing routing modules import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-news', templateUrl: './news.component.html', styleUrls: ['./news.component.scss'] }) export class NewsComponent implements OnInit { constructor(private route: ActivatedRoute) { } ngOnInit(): void { this.route.queryParamMap.subscribe((data: any) => { console.log(data.params); }); } }4.2.2, Dynamic Routing
Unlike query parameters, dynamic routing requires placeholder information for parameters when defining a route, such as in the code that defines the route below, for the parameter newsId required by the component, we need to specify when defining the route
const routes: Routes = [ { path: 'news/detail/:newsId', component: NewsDetailComponent }, ];
For route jumps using dynamic routing, we need to specify the parameter values we pass in the second data of the routerLink property array bound by the a tag.For example, the item.newsId variable here is the parameter value that we need to pass in
<ul> <li *ngFor="let item of newsList; let i = index"> <a [routerLink]="['/news/detail', item.newsId]" routerLinkActive="active" > {} </a> </li> </ul>
When jumping by js, we also need to inject the Router class by injection dependency and call the navigate method to jump.Unlike passing data using query query parameters, you need to combine jumped links with corresponding parameter values into an array parameter to pass
import { Component, OnInit } from '@angular/core'; // Introducing routing modules import { Router, ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-news', templateUrl: './news.component.html', styleUrls: ['./news.component.scss'] }) export class NewsComponent implements OnInit { newsList: any; constructor(private route: ActivatedRoute, private router: Router) { this.newsList = [{ newsId: 1111, title: 'lalalalalallaaa' }, { newsId: 2222, title: 'lalalalalallaaa' }, { newsId: 3333, title: 'lalalalalallaaa' }]; } ngOnInit(): void { this.route.queryParamMap.subscribe((data: any) => { console.log(data.params); }); } routerNavigate() { this.router.navigate(['/news/detail', 11111]); } }
In the component classes that get parameter data, you need to rely on injecting the ActivatedRoute class, because parameter passing is done by dynamic routing, where you need to get the corresponding parameter value through the paramMap property
import { Component, OnInit } from '@angular/core'; // Introducing routing modules import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-news-detail', templateUrl: './news-detail.component.html', styleUrls: ['./news-detail.component.scss'] }) export class NewsDetailComponent implements OnInit { constructor(private route: ActivatedRoute) { } ngOnInit(): void { this.route.paramMap.subscribe((data: any) => { console.log(data.params); }); } }4.3, Nested Routing
In some cases, there are nested relationships between routes, such as this page below, which only shows the menus on the left when we click on the menu on the top of Resources, that is, the parent menu of the menu on the left side of this page is the resource menu on the top
For such nested routes, when defining a route, we need to specify the nested relationship between routes by configuring the children attribute, for example, here I define a nested relationship between the ProductDetailComponent component and the routes formed by the ProductComponent component.
// Configure Routing Information const routes: Routes = [ { path: 'product', component: ProductComponent, children: [{ path: 'detail', component: ProductDetailComponent }, { path: '', redirectTo: 'detail', pathMatch: 'full' }] } ];
Since the rendering outlet for the child route is on the parent route page, when the nested route configuration is complete, on the nested parent page, we need to define a <router-outlet>label to specify the rendering outlet for the child route, and the final effect is as follows
<h3>I'm the parent route page displays </h3> <p>product works!</p> <!--Load subrouting data--> <h3>Export rendered by subrouting component</h3> <router-outlet></router-outlet>