Le routage est au cœur de l'application Angular Cet article vous amènera à comprendre Angular Router et à présenter en détail la différence entre l'utilisation de naviguer() et naviguerByUrl().
Le routage est le cœur d'une application Angular, chargeant les composants associés à l'itinéraire demandé et obtenant les données pertinentes pour un itinéraire spécifique. Cela nous permet de contrôler différents itinéraires, d'obtenir différentes données et de restituer différentes pages. [Tutoriels associés recommandés : "Tutoriel angulaire"]
Tout d'abord, nous devons installer Angular Router. Vous pouvez le faire en exécutant l'une des opérations suivantes :
yarn add @angular/router # OR npm i --save @angular/router
Une fois la commande ci-dessus exécutée, le module @angular/router
sera automatiquement téléchargé dans le dossier node_modules
.
La dernière chose que nous devons faire est d'ajouter la balise <base>
à notre fichier index.html. Les routeurs en ont besoin pour déterminer le répertoire racine de l'application. Par exemple, lorsque nous allons sur http://example.com/page1
, si nous ne définissons pas le chemin de base de notre application, le routeur ne saura pas si l'adresse d'hébergement de notre application est http://example.com
ou http://example.com/page1
.
C'est très simple à faire. Ouvrez simplement le fichier index.html
dans le projet et ajoutez la balise <base>
correspondante, comme suit :
<!doctype html> <html> <head> <base href="/"> <title>Application</title> </head> <body> <app-root></app-root> </body> </html>
Les informations de configuration ci-dessus indiquent le routage angulaire, Le répertoire racine de l'application est /
.
Pour utiliser le routage, nous devons importer RouterModule dans le module AppModule. Les détails sont les suivants :
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 {}
À l'heure actuelle, notre routage ne fonctionne pas correctement car nous n'avons pas configuré les informations de routage de l'application. L'objet RouterModule nous fournit deux méthodes statiques : forRoot()
et forChild()
pour configurer les informations de routage. La méthode
RouterModule.forRoot()
est utilisée pour définir les principales informations de routage dans le module principal. En appelant cette méthode, notre module principal peut accéder. Toutes les directives définies dans le module de routage. Voyons ensuite comment utiliser forRoot()
:
// ... import { Routes, RouterModule } from '@angular/router'; export const ROUTES: Routes = []; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}
Nous définissons les informations de configuration de la route en utilisant const, puis appelons la méthode RouterModule.forRoot()
comme paramètre au lieu d'utiliser RouterModule.forRoot([...])
directement , l'avantage est que cela nous permet d'exporter ROUTES
vers d'autres modules en cas de besoin.
RouterModule.forChild()
est similaire à la méthode Router.forRoot()
, mais elle ne peut être appliquée que dans les modules de fonctionnalités.
Astuce : utilisez forRoot()
dans le module racine et forChild()
dans les sous-modules. Cette fonctionnalité est très puissante car nous n'avons pas besoin de définir toutes les informations de routage en un seul endroit (notre module principal). Au lieu de cela, nous pouvons définir des informations de routage spécifiques au module dans le module de fonctionnalités et les importer dans notre module principal si nécessaire. L'utilisation de RouterModule.forChild()
est la suivante :
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 {}
Grâce à l'exemple ci-dessus, nous savons que les types d'objets de configuration de routage sont les mêmes dans le module principal et dans le module de fonctionnalités. La différence est que différentes méthodes sont nécessaires. à appeler dans le module principal et le module de fonctionnalités Méthode pour configurer le routage du module. Voyons ensuite comment configurer l'objet ROUTES
.
Tous les itinéraires que nous définissons sont en tant qu'objets dans le tableau ROUTES. Tout d'abord, définissez un itinéraire pour notre page d'accueil :
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 {}
Dans l'exemple, nous définissons le chemin correspondant de l'itinéraire via l'attribut path, et l'attribut composant est utilisé pour définir le composant qui doit être chargé lorsque le l'itinéraire correspond.
Rappel amical : Nous utilisons path: ''
pour faire correspondre les chemins vides, par exemple : https://yourdomain.com
Après avoir configuré les informations de routage , l'étape suivante consiste à indiquer à Angular où charger le composant à l'aide d'une directive appelée router-outlet
. Lorsque la route angulaire correspond au chemin de réponse et trouve avec succès le composant qui doit être chargé, elle créera dynamiquement le composant correspondant et l'insérera dans l'élément router-outlet
en tant qu'élément frère.
Dans notre composant AppComponent, nous pouvons insérer la directive router-outlet
n'importe où :
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div class="app"> <h3>Our app</h3> <router-outlet></router-outlet> </div> ` }) export class AppComponent {}
Maintenant que nous avons établi la route principale de l'application, nous pouvons en apprendre davantage sur les autres options de configuration de l'itinéraire.
Ce que nous avons introduit jusqu'à présent n'est que le début, jetons un coup d'œil à quelques autres options et fonctionnalités.
Itinéraires dynamiques
如果路由始终是静态的,那没有多大的用处。例如 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: ` <div class="profile"> <h3>{{ username }}</h3> </div> ` }) export class SettingsComponent implements OnInit { username: string; constructor(private route: ActivatedRoute) {} ngOnInit() { this.route.params.subscribe((params) => this.username = params.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: ` <div class="settings"> <settings-header></settings-header> <settings-sidebar></settings-sidebar> <router-outlet></router-outlet> </div> ` }) 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 指令,具体示例如下:
<nav> <a routerLink="/">Home</a> <a routerLink="/settings/password">Change password</a> <a routerLink="/settings/profile">Profile Settings</a> </nav>
当我们点击以上的任意链接时,页面不会被重新加载。反之,我们的路径将在 URL 地址栏中显示,随后进行后续视图更新,以匹配 routerLink 中设置的值。
友情提示:我们也可以将 routerLink 的属性值,改成数组形式,以便我们传递特定的路由信息
如果我们想要链接到动态的路由地址,且该地址有一个 username 的路由变量,则我们可以按照以下方式配置 routerLink 对应的属性值:
<a [routerLink]="['/profile', username]"> Go to {{ username }}'s profile. </a>
在实际开发中,我们需要让用户知道哪个路由处于激活状态,通常情况下我们通过向激活的链接添加一个 class 来实现该功能。为了解决上述问题,Angular 路由模块为我们提供了 routerLinkActive 指令,该指令的使用示例如下:
<nav> <a routerLink="/settings" routerLinkActive="active">Home</a> <a routerLink="/settings/password" routerLinkActive="active">Change password</a> <a routerLink="/settings/profile" routerLinkActive="active">Profile Settings</a> </nav>
通过使用 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: ` <div class="app"> <h3>Our app</h3> <router-outlet></router-outlet> </div> ` }) 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: ` <div class="app"> <h3>Our app</h3> <router-outlet></router-outlet> </div> ` }) 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: ` <div class="app"> <h3>Users</h3> <div *ngFor="let user of users"> <user-component [user]="user" (select)="handleSelect($event)"> </user-component> </div> <router-outlet></router-outlet> </div> ` }) 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
<a [routerLink]="['/router', '823712312938123', {h:'h',c:'c'}]" [queryParams]="{code:'code'}">RouterLink 跳转</a> <a (click)="goToDetail()">Navigate 跳转</a>
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)
。
更多编程相关知识,请访问:编程入门!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!