Home>Article>Web Front-end> A brief discussion on the difference between the usage methods of navigate() and navigateByUrl() in Angular
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().
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"]
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/router
module will be automatically downloaded to thenode_modules
folder middle.
The last thing we need to do is add the
tag 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.com
orhttp://example.com/page1
.
This is very simple to do. Just open theindex.html
file in the project and add the corresponding
tag, as follows:
Application
The above configuration information tells Angular routing that the root directory of the application is/
.
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()
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 exportROUTES
to other modules when needed. middle.
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 theROUTES
object.
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
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 the
router-outletelement as a sibling element.
router-outletdirective anywhere:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: `We have now established the main route of the application, we can go further Learn about other configuration options for routing.` }) export class AppComponent {}Our app
如果路由始终是静态的,那没有多大的用处。例如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: `` }) export class SettingsComponent implements OnInit { username: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.params.subscribe((params) => this.username = params.username); } }{{ username }}
介绍完动态路由,我们来探讨一下如何创建 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 路由。使用 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
元素中。
我们也可以告诉路由从另一个模块中获取子路由。这将我们谈论的两个想法联系在一起 - 我们可以指定另一个模块中定义的子路由,以及通过将这些子路由设置到特定的路径下,来充分利用 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-outlet
指令,路由模块中还提供了一些其它指令。让我们来看看它们如何与我们之前介绍的内容结合使用。
为了让我们链接到已设置的路由,我们需要使用 routerLink 指令,具体示例如下:
当我们点击以上的任意链接时,页面不会被重新加载。反之,我们的路径将在 URL 地址栏中显示,随后进行后续视图更新,以匹配 routerLink 中设置的值。
友情提示:我们也可以将 routerLink 的属性值,改成数组形式,以便我们传递特定的路由信息
如果我们想要链接到动态的路由地址,且该地址有一个 username 的路由变量,则我们可以按照以下方式配置 routerLink 对应的属性值:
Go to {{ username }}'s profile.
在实际开发中,我们需要让用户知道哪个路由处于激活状态,通常情况下我们通过向激活的链接添加一个 class 来实现该功能。为了解决上述问题,Angular 路由模块为我们提供了 routerLinkActive 指令,该指令的使用示例如下:
通过使用 routerLinkActive 指令,当a
元素对应的路由处于激活状态时,active
类将会自动添加到a
元素上。
最后,我们来简单介绍一下 Router API。
我们可以通过路由还提供的 API 实现与 routerLink 相同的功能。要使用 Router API,我们需要在组件类中注入 Router 对象,具体如下:
import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: `` }) export class AppComponent { constructor(private router: Router) {} }Our app
组件类中注入的 router 对象中有一个navigate()
方法,该方法支持的参数类型与 routerLink 指令一样,当调用该方法后,页面将会自动跳转到对应的路由地址。具体使用示例如下:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: `` }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit() { setTimeout(() => { this.router.navigate(['/settings']); }, 5000); } }Our app
若以上代码成功运行,用户界面将在 5 秒后被重定向到/settings
页面。这个方法非常有用,例如当检测到用户尚未登录时,自动重定向到登录页面。
另一个使用示例是演示页面跳转时如何传递数据,具体如下:
import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-root', template: `` }) 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]); } }Users
Angular 路由的功能非常强大,既可以使用指令方式也可以使用命令式 API,希望本文可以帮助你尽快入门,若要进一步了解路由详细信息,请访问 - Angular Router 官文文档。
路由传参示例/router/823712312938123;h=h;c=c?code=code
RouterLink 跳转 Navigate 跳转
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) } }
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!