Home>Article>Web Front-end> A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular

A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular

青灯夜游
青灯夜游 forward
2021-06-25 11:55:46 2603browse

Routing is the core ofAngularapplication. This article will take you to understand Angular Router and introduce in detail the difference between the usage of navigate() and navigateByUrl().

A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular

Routing is the heart of an Angular application, loading the components associated with the requested route and getting the relevant data for a specific route. This allows us to render different pages by controlling different routes and obtaining different data. [Related tutorial recommendations: "angular tutorial"]

Installing the router

First thing first, we need to install Angular Router. You can do this by running any of the following operations:

yarn add @angular/router # OR npm i --save @angular/router

After the above command is executed, the@angular/routermodule will be automatically downloaded to thenode_modulesfolder middle.

Base href

The last thing we need to do is add thetag to our index.html file middle. Routers need this to determine the root directory of the application. For example, when we go tohttp://example.com/page1, if we don't define the base path of our application, the router won't know that our app's hosting address ishttp:// /example.comorhttp://example.com/page1.

This is very simple to do. Just open theindex.htmlfile in the project and add the correspondingtag, as follows:

    Application 

The above configuration information tells Angular routing that the root directory of the application is/.

Using the router

To use routing, we need to import RouterModule in the AppModule module. The details are as follows:

import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule, RouterModule ], bootstrap: [ AppComponent ], declarations: [ AppComponent ] }) export class AppModule {}

At this time, our routing is not working properly because we have not configured the relevant information of application routing. The RouterModule object provides us with two static methods:forRoot()andforChild()to configure routing information.

RouterModule.forRoot()

RouterModule.forRoot()method is used to define the main routing information in the main module. By calling this Method gives our main module access to all directives defined in the routing module. Next, let’s take a look at how to useforRoot():

// ... import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = []; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}

We define the routing configuration information by using const, and then call it as a parameterRouterModule.forRoot()method instead of usingRouterModule.forRoot([...])directly. The advantage of this method is that it is convenient for us to exportROUTESto other modules when needed. middle.

RouterModule.forChild()

RouterModule.forChild()is similar to theRouter.forRoot()method, but It can only be used in feature modules.
Friendly reminder: useforRoot()in the root module andforChild()
in the submodule. This function is very powerful because we don’t have to do it in one place (our Main module) defines all routing information. Instead, we can define module-specific routing information in the feature module and import them into our main module when necessary.RouterModule.forChild()is used as follows:

import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = []; @NgModule({ imports: [ CommonModule, RouterModule.forChild(ROUTES) ], // ... }) export class ChildModule {}

Through the above example, we know that the type of routing configuration object is the same in the main module and the feature module, the difference is only in the main module Different methods need to be called in the feature module to configure module routing. Next, let’s introduce how to configure theROUTESobject.

Configuring a route

All routes we define are as objects in the ROUTES array. First, define a route for our homepage:

import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; export const ROUTES: Routes = [ { path: '', component: HomeComponent } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}

In the example, we define the matching path of the route through the path attribute, and the component attribute is used to define the component that needs to be loaded when the route is matched.

Friendly reminder: We usepath: ''to match empty paths, for example:https://yourdomain.com

# #Displaying routes

After configuring the routing information, the next step is to use a directive called

router-outletto tell Angular where to load the component. When Angular routing matches the response path and successfully finds the component that needs to be loaded, it will dynamically create the corresponding component and insert it into therouter-outletelement as a sibling element.

In our AppComponent component, we can insert the

router-outletdirective anywhere:

import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` 

Our app

` }) export class AppComponent {}

We have now established the main route of the application, we can go further Learn about other configuration options for routing.

Further configuration

What we have introduced so far is just the beginning, let's take a look at some other options and functions.

Dynamic routes

如果路由始终是静态的,那没有多大的用处。例如path: ''是加载我们 HomeComponent 组件的静态路由。我们将介绍动态路由,基于动态路由我们可以根据不同的路由参数,渲染不同的页面。

例如,如果我们想要在个人资料页面根据不同的用户名显示不同的用户信息,我们可以使用以下方式定义路由:

import { HomeComponent } from './home/home.component'; import { ProfileComponent } from './profile/profile.component'; export const ROUTES: Routes = [ { path: '', component: HomeComponent }, { path: '/profile/:username', component: ProfileComponent } ];

这里的关键点是 : ,它告诉 Angular 路由,:username是路由参数,而不是 URL 中实际的部分。

友情提示:如果没有使用 : ,它将作为静态路由,仅匹配/profile/username路径
现在我们已经建立一个动态路由,此时最重要的事情就是如何获取路由参数。要访问当前路由的相关信息,我们需要先从@angular/router模块中导入ActivatedRoute,然后在组件类的构造函数中注入该对象,最后通过订阅该对象的 params 属性,来获取路由参数,具体示例如下:

import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'profile-page', template: ` 

{{ username }}

` }) export class SettingsComponent implements OnInit { username: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.params.subscribe((params) => this.username = params.username); } }

介绍完动态路由,我们来探讨一下如何创建 child routes。

Child routes

实际上每个路由都支持子路由,假设在我们/settings设置页面下有/settings/profile/settings/password两个页面,分别表示个人资料页和修改密码页。

我们可能希望我们的/settings页面拥有自己的组件,然后在设置页面组件中显示/settings/profile/settings/password页面。我们可以这样做:

import { SettingsComponent } from './settings/settings.component'; import { ProfileSettingsComponent } from './settings/profile/profile.component'; import { PasswordSettingsComponent } from './settings/password/password.component'; export const ROUTES: Routes = [ { path: 'settings', component: SettingsComponent, children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], }) export class AppModule {}

在这里,我们在 setttings 路由中定义了两个子路由,它们将继承父路由的路径,因此修改密码页面的路由匹配地址是/settings/password,依此类推。

接下来,我们需要做的最后一件事是在我们的 SettingsComponent 组件中添加router-outlet指令,因为我们要在设置页面中呈现子路由。如果我们没有在 SettingsComponent 组件中添加router-outlet指令,尽管/settings/password匹配修改密码页面的路由地址,但修改密码页面将无法正常显示。具体代码如下:

import { Component } from '@angular/core'; @Component({ selector: 'settings-page', template: ` 
` }) export class SettingsComponent {}

Component-less routes

另一个很有用的路由功能是 component-less 路由。使用 component-less 路由允许我们将路由组合在一起,并让它们共享路由配置信息和 outlet。

例如,我们可以定义 setttings 路由而不需要使用 SettingsComponent 组件:

import { ProfileSettingsComponent } from './settings/profile/profile.component'; import { PasswordSettingsComponent } from './settings/password/password.component'; export const ROUTES: Routes = [ { path: 'settings', children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], }) export class AppModule {}

此时,/settings/profile/settings/password路由定义的内容,将显示在 AppComponent 组件的router-outlet元素中。

loadChildren

我们也可以告诉路由从另一个模块中获取子路由。这将我们谈论的两个想法联系在一起 - 我们可以指定另一个模块中定义的子路由,以及通过将这些子路由设置到特定的路径下,来充分利用 component-less 路由的功能。

让我们创建一个 SettingsModule 模块,用来保存所有 setttings 相关的路由信息:

import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = [ { path: '', component: SettingsComponent, children: [ { path: 'profile', component: ProfileSettingsComponent }, { path: 'password', component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ CommonModule, RouterModule.forChild(ROUTES) ], }) export class SettingsModule {}

需要注意的是,在 SettingsModule 模块中我们使用forChild()方法,因为 SettingsModule 不是我们应用的主模块。

另一个主要的区别是我们将 SettingsModule 模块的主路径设置为空路径 (’’)。因为如果我们路径设置为/settings,它将匹配/settings/settings,很明显这不是我们想要的结果。通过指定一个空的路径,它就会匹配/settings路径,这就是我们想要的结果。

那么/settings路由信息,需要在哪里配置?答案是在 AppModule 中。这时我们就需要用到 loadChildren 属性,具体如下:

export const ROUTES: Routes = [ { path: 'settings', loadChildren: () => import('./settings/settings.module').then(it => it.SettingsModule) } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}

需要注意的是,我们没有将 SettingsModule 导入到我们的 AppModule 中,而是通过 loadChildren 属性,告诉 Angular 路由依据 loadChildren 属性配置的路径去加载 SettingsModule 模块。这就是模块懒加载功能的具体应用,当用户访问/settings/**路径的时候,才会加载对应的 SettingsModule 模块,这减少了应用启动时加载资源的大小。

另外我们传递一个字符串作为 loadChildren 的属性值,该字符串由三部分组成:

需要导入模块的相对路径 # 分隔符 导出模块类的名称

了解完路由的一些高级选项和功能,接下来我们来介绍路由指令。

Router Directives

除了router-outlet指令,路由模块中还提供了一些其它指令。让我们来看看它们如何与我们之前介绍的内容结合使用。

routerLink

为了让我们链接到已设置的路由,我们需要使用 routerLink 指令,具体示例如下:

当我们点击以上的任意链接时,页面不会被重新加载。反之,我们的路径将在 URL 地址栏中显示,随后进行后续视图更新,以匹配 routerLink 中设置的值。

友情提示:我们也可以将 routerLink 的属性值,改成数组形式,以便我们传递特定的路由信息
如果我们想要链接到动态的路由地址,且该地址有一个 username 的路由变量,则我们可以按照以下方式配置 routerLink 对应的属性值:

 Go to {{ username }}'s profile. 

routerLinkActive

在实际开发中,我们需要让用户知道哪个路由处于激活状态,通常情况下我们通过向激活的链接添加一个 class 来实现该功能。为了解决上述问题,Angular 路由模块为我们提供了 routerLinkActive 指令,该指令的使用示例如下:

通过使用 routerLinkActive 指令,当a元素对应的路由处于激活状态时,active类将会自动添加到a元素上。
最后,我们来简单介绍一下 Router API。

Router API

我们可以通过路由还提供的 API 实现与 routerLink 相同的功能。要使用 Router API,我们需要在组件类中注入 Router 对象,具体如下:

import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` 

Our app

` }) export class AppComponent { constructor(private router: Router) {} }

组件类中注入的 router 对象中有一个navigate()方法,该方法支持的参数类型与 routerLink 指令一样,当调用该方法后,页面将会自动跳转到对应的路由地址。具体使用示例如下:

import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` 

Our app

` }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit() { setTimeout(() => { this.router.navigate(['/settings']); }, 5000); } }

若以上代码成功运行,用户界面将在 5 秒后被重定向到/settings页面。这个方法非常有用,例如当检测到用户尚未登录时,自动重定向到登录页面。

另一个使用示例是演示页面跳转时如何传递数据,具体如下:

import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: ` 

Users

` }) export class AppComponent implements OnInit { users: Username[] = [ { name: 'toddmotto', id: 0 }, { name: 'travisbarker', id: 1 }, { name: 'tomdelonge', id: 2 } ]; constructor(private router: Router) {} handleSelect(event) { this.router.navigate(['/profile', event.name]); } }

Angular 路由的功能非常强大,既可以使用指令方式也可以使用命令式 API,希望本文可以帮助你尽快入门,若要进一步了解路由详细信息,请访问 - Angular Router 官文文档。

路由传参示例
/router/823712312938123;h=h;c=c?code=code

  • HTML:
RouterLink 跳转 Navigate 跳转
  • TS:
this.router.navigate([`router/823712312938123`, {h: 'h', c: 'c'}], {queryParams: {code: 'code'}})

在component中取数据
router-demo.component.ts

import {Component, OnInit} from '@angular/core' import {ActivatedRoute} from '@angular/router' @Component({ selector: 'app-router-demo', templateUrl: './router-demo.component.html', styleUrls: ['./router-demo.component.less'] }) export class RouterDemoComponent implements OnInit { constructor(private activatedRoute: ActivatedRoute) { } ngOnInit(): void { const {params, queryParams} = this.activatedRoute.snapshot console.log('params', params) console.log('queryParams', queryParams, queryParams) } }

A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular

Angular Router API 提供了navigate()navigateByUrl()两个方法来实现页面导航。两者区别如下:

  • 使用router.navigateByUrl()方法与直接改变地址栏上的 URL 地址一样,我们使用了一个新的 URL 地址。
  • 然而router.navigate()方法基于一系列输入参数,产生一个新的 URL 地址。

为了更好理解两者区别,有例子,假设当前的 URL 地址是:

/inbox/11/message/22(popup:compose)

当调用router.navigateByUrl('/inbox/33/message/44')方法后,当前的 URL 地址将变成/inbox/33/message/44

但若是调用router.navigate('/inbox/33/message/44')方法,当前的 URL 地址将变成/inbox/33/message/44(popup:compose)

更多编程相关知识,请访问:编程入门!!

The above is the detailed content of A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete