This is the sixth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

preface

The concept of routing has been widely used in the front-end framework. The concept of routing is not described. The application of routing is nothing more than nesting, parameter passing, some advanced functions such as lazy loading, preloading, and some more advanced functions such as routing guard. In this article, let’s take a look at how routing is used in Angular.

Please follow the structure shown in the diagram to create our project

Create project & Level 1 module:
  1. ng new angular-router-sample
  2. ng g c pages/login
  3. ng g c pages/home
  4. ng g c pages/mine

Note: Components created through the CLI are automatically registered.

start

1. Configure in the HTML template of the App

Configuring router-outlets

<div>
  <a [routerLink] ="['/login']">landing</a>|<a [routerLink] ="['/home']">Home page</a>|<a [routerLink] ="['/mine']">my</a>
</div>
<! -- Configure the route egress -->
<router-outlet></router-outlet>
Copy the code

2. Configure the router in app-Routing of the App

  1. The simplest component route requires a path (the Url of the route) property and a Component (the component to which the Url is loaded) property:
const routes: Routes = [
  {
    path: 'login'.component: LoginComponent,
  },
  {
    path: 'home'.component: HomeComponent,
  },
  {
    path: 'mine'.component: MineComponent,
  },
];
Copy the code
  1. What happens to our 404 page when we accidentally visit a Url that doesn’t exist?

Path supports a special wildcard character to support “**” and points to the corresponding wildcard component when there is no successful match in the routing table

const routes: Routes = [
  ...
  {
    path: '* *'.component: NotFountComponent,
  },
];
Copy the code

Note: The router matching policy is first come, first served. Therefore, the configuration of non-specific routes is configured later.

3. Set a valid default route

Since our project has no specific route match after starting by default, which is not friendly, we need to set a valid default route to show the user.

  1. The default route must be higher than the wildcard route.
const routes: Routes = [
  ...
  { path: ' '.redirectTo: '/home'.pathMatch: 'full' },
  ...
];
Copy the code

Configure submodules and subroutes

At this time, our routing configuration is all app-routing, which is of course feasible for simple applications. However, with the iteration of applications and the increase of modules, it is obvious that the configuration together is a challenge for management and extension, so the separation of modules is inevitable.

1. Add a module configuration with routing for the Home component

On the CLI, run the ng generate module pages/home/home –module app –flat –routing command to create a module configuration for the Home component

imports: [
    BrowserModule,
    HomeRoutingModule,
    AppRoutingModule,
]
Copy the code

Note: Modules created using the CLI are automatically configured to the root module, but we manually changed the order to move the AppRoutingModule to the end to satisfy the first come, first served policy.

2. Transfer the route configuration of the Home component tohome-routing

const routes: Routes = [{
  path: 'home'.component: HomeComponent,
}];
Copy the code

Note: Once configured, you can remove the Home component configuration from app-Routing.

3. Add child components of the Home group module and configure child routes

  1. Execute the command to create the child component
    1. ng g c pages/home/children/user-list
    2. ng g c pages/home/children/user-detail
    3. ng g c pages/home/children/edit-user
  2. Added to the Home router configurationchildrenProperty to configure sub-component routing
const routes: Routes = [{
  ...
  children: [{path: 'list'.component: UserListComponent,
    },
    {
      path: 'detail'.component: UserDetailComponent,
    },
    {
      path: 'edit'.component: EditUserComponent,
    },
    {
      path: ' '.redirectTo: '/home/list'.pathMatch: 'full'}}]];Copy the code
  1. Configure routing egress for submodules as for root components
<div>
  <a [routerLink] ="['/home/list']">The list of</a>| < a [routerLink] ="['/home/edit']"</a> | <a [routerLink]="['/home/detail']"Word-wrap: break-word! Important; "> < div style =" text-align: center; -- Configure the route egress --><router-outlet></router-outlet>
Copy the code

Routing and the cords

1. Configure the parameter tokens to be carried during route definition

  1. Format: Add the format to the path of the route configuration/:keyIs a placeholder for the token
{
  path: 'detail/:id'.component: UserDetailComponent
}
Copy the code

Note: Id is a mandatory parameter in this way of inserting tokens into the route path.

  1. throughrouterLinkWith parameters
<a [routerLink]="['/hero', hero.id]">
Copy the code
  1. Angular uses the ActivatedRoute to obtain route parameters:

Inject the ActivatedRoute into the target component before using the ActivatedRoute

  1. Method 1: Obtain parameters (route parameter changes can be monitored, applicable to the case of multiple reuse of the same component instance)
this.route.paramMap.subscribe(
  (params: ParamMap) = > {
    console.log('id :>> ', params.get('id')); })Copy the code
  1. Method 2: Obtain parameters (initial values only)
const id = this.route.snapshot.paramMap.get('id')! ;Copy the code

ParamMap API:

Members of the instructions
has(name) Returns if the parameter name is in the parameter listtrue.
get(name) If the map has a parameter value (string) corresponding to the parameter name, return it, otherwisenull. If the parameter value is actually an array, return its first element.
getAll(name) Return an array of strings if the map has values corresponding to the parameter names, or an empty array otherwise. Use this parameter when a parameter name may have multiple valuesgetAll.
keys Returns a string array of all parameter names in the map.

2. Navigate to the Navigate page of the Router

The current component injects a Router object

  1. Carry jump with no parameter:
this.router.navigate(['/home/list']);
Copy the code
  1. Jump with parameters:
this.router.navigate(['/home/list', { id: this.userId, name: this.userName }]);
Copy the code

Note: Matrix URL notation:; id=101; name=bom

Lazy loading

The purpose of lazy loading is to delay the mounting of the module until we use it, so as to avoid the whole page being unavailable for a long time when the page is loaded the first time it is opened.

1. Configure no-component routing (empty routing).

Group routes without adding additional path fragments

{
    path: 'home'.loadChildren: () = >
      import('./pages/home/home.module').then((m) = > m.HomeModule),
}
Copy the code

2. Remove the Home module import from the root module to separate the Home module completely

– Fine-tuned home routing path to “”

const routes: Routes = [{
  path: ' '.component: HomeComponent,
  children: [...]. }];Copy the code

3. Preload as opposed to lazy load

Angular configulates lazy loading of modules to be delayed until they are used, but some components need to be loaded first and run when they are used.

The Router module in Angular provides two preloading strategies:

  1. No preloading at all, this is the default. Lazy-loaded feature areas are still loaded on demand.
  2. Preload all lazy-loaded feature areas.
  3. Change the mode: The object in parameter 2 of RouterModule.forroot () supports load mode propertiespreloadingStrategy.
    1. PreloadAllModules: Preloads certain modules
    2. NoPreloading: default, NoPreloading is performed
  4. These properties must support customization. Let’s take a look:
    1. Add a data object to the route configuration object that needs to be preloaded and add itpreloadProperty with the value set totrueIndicates that preloading is enabled.
    2. Using the CLI to generate a service to complete our preload strategy:ng generate service selective-preloading-strategy
    3. Implement the interface to the service we createdPreloadingStrategy
    4. The user-defined policies and the default policies are used in the same way.
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root',})export class SelectivePreloadingStrategyService implements PreloadingStrategy {
  preloadedModules: string[] = [];

  preload(route: Route, fn: () = > Observable<any>): Observable<any> {
    // Check the route configuration to determine whether to preload
    if(route.data && route.data.preload && route.path ! =null) {
      Parameter 1: indicates the route to be loaded
      this.preloadedModules.push(route.path);
      // Parameter 2: loader
      return fn();
    } else {
      return of(null); }}}Copy the code

conclusion

So that’s all we’ve learned recently about Angular routing. There’s one piece of routing that we didn’t mention, but we’ll do it again sometime.