今回は Angular ルーティング ガードを使用する手順について詳しく説明します。 Angular ルーティング ガードを使用する際の 注意事項 は何ですか?実際のケースを見てみましょう。
1. ルートガード
ユーザーは、特定の条件を満たした場合にのみルートに出入りできます。 ルート ガード シナリオ: ユーザーがログインし、特定の権限を持っている場合にのみ、特定のルートに入ることができます。 登録プロセスなどの複数のフォームで構成されるウィザード。ユーザーは、現在のルートのコンポーネントに必要な情報を入力した場合にのみ、次のルートに移動できます。
保存操作を実行せずに現在のナビゲーションを終了しようとすると、ユーザーに警告します。
Angular は、ルートの出入りを制御するためのフックをいくつか提供します。これらのフックはルーティング ガードであり、上記のシナリオはこれらのフックを通じて実現できます。
2. CanActivate例: ログインしたユーザーのみに製品情報ルーティングの入力を許可します。
新しいガードディレクトリを作成します。ディレクトリに新しいlogin.guard.tsを作成します。
LoginGuard クラスは CanActivate インターフェイスを実装し、Angular は戻り値に基づいてリクエストが成功するか失敗するかを決定します。
import { CanActivate } from "@angular/router"; export class LoginGuard implements CanActivate{ canActivate(){ let loggedIn :boolean= Math.random()<0.5; if(!loggedIn){ console.log("用户未登录"); } return loggedIn; } }
製品のルーティングを設定します。まず LoginGuard をプロバイダーに追加し、次にルーティング ガードを指定します。
canActivate は複数のガードを指定でき、値は配列です。
const routes: Routes = [ { path: '', redirectTo : 'home',pathMatch:'full' }, { path: 'chat', component: ChatComponent, outlet: "aux"},//辅助路由 { path: 'home', component: HomeComponent }, { path: 'product/:id', component: ProductComponent, children:[ { path: '', component : ProductDescComponent }, { path: 'seller/:id', component : SellerInfoComponent } ] ,canActivate: [LoginGuard]}, { path: '**', component: Code404Component } ];
効果:
製品詳細リンク コンソールをクリックすると、ログインしていないため製品詳細ルートに入ることができないことをユーザーに通知します。
3. 出発時にルートガードを無効化できます。終了する前に保存するようユーザーに通知します。
guard ディレクトリに新しい unsave.guard.ts ファイルを作成します。
CanDeactivate インターフェースには、現在のコンポーネントのタイプを指定するジェネリックタイプがあります。
CanDeactivate メソッドの最初のパラメーターは、インターフェイスによって指定されたジェネリック型のコンポーネントであり、保護されるコンポーネントのステータスに基づいて、またはユーザーが終了できるかどうかを決定するメソッドを呼び出します。
import { CanDeactivate } from "@angular/router"; import { ProductComponent } from "../product/product.component"; export class UnsaveGuard implements CanDeactivate<ProductComponent>{ //第一个参数 范型类型的组件 //根据当前要保护组件 的状态 判断当前用户是否能够离开 canDeactivate(component: ProductComponent){ return window.confirm('你还没有保存,确定要离开吗?'); } }
ルートの設定も最初にプロバイダーに追加してからルートを設定します。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { ProductComponent } from './product/product.component'; import { Code404Component } from './code404/code404.component'; import { ProductDescComponent } from './product-desc/product-desc.component'; import { SellerInfoComponent } from './seller-info/seller-info.component'; import { ChatComponent } from './chat/chat.component'; import { LoginGuard } from './guard/login.guard'; import { UnsaveGuard } from './guard/unsave.guard'; const routes: Routes = [ { path: '', redirectTo : 'home',pathMatch:'full' }, { path: 'chat', component: ChatComponent, outlet: "aux"},//辅助路由 { path: 'home', component: HomeComponent }, { path: 'product/:id', component: ProductComponent, children:[ { path: '', component : ProductDescComponent }, { path: 'seller/:id', component : SellerInfoComponent } ] ,canActivate: [LoginGuard], canDeactivate: [UnsaveGuard]}, { path: '**', component: Code404Component } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [LoginGuard,UnsaveGuard] }) export class AppRoutingModule { }
効果:
[OK] をクリックして現在のページを終了し、キャンセルして現在のページに留まります。
4. ガードを解決します http リクエスト データを返すのに遅れが生じ、その結果、テンプレートがすぐに表示されません。
データが返される前は、コントローラーの値を表示するために補間
式を使用する必要があるテンプレート上のすべての場所が空になっています。ユーザーエクスペリエンスは良くありません。 解決策: ルーティングを入力する前にサーバーにアクセスしてデータを読み取り、必要なデータをすべて読み取った後、データを含むルーティングを入力し、すぐにデータを表示します。
例:
商品情報のルーティングを入力する前に、商品情報を準備してからルーティングを入力してください。 情報を取得できない場合、または情報の取得に問題がある場合は、
エラーメッセージページに直接ジャンプするか、プロンプトがポップアップ表示され、目的のルートに入ることはできません。 まずproduct.component.tsで商品情報の型を宣言します。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { ProductComponent } from './product/product.component'; import { Code404Component } from './code404/code404.component'; import { ProductDescComponent } from './product-desc/product-desc.component'; import { SellerInfoComponent } from './seller-info/seller-info.component'; import { ChatComponent } from './chat/chat.component'; import { LoginGuard } from './guard/login.guard'; import { UnsaveGuard } from './guard/unsave.guard'; const routes: Routes = [ { path: '', redirectTo : 'home',pathMatch:'full' }, { path: 'chat', component: ChatComponent, outlet: "aux"},//辅助路由 { path: 'home', component: HomeComponent }, { path: 'product/:id', component: ProductComponent, children:[ { path: '', component : ProductDescComponent }, { path: 'seller/:id', component : SellerInfoComponent } ] ,canActivate: [LoginGuard], canDeactivate: [UnsaveGuard]}, { path: '**', component: Code404Component } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [LoginGuard,UnsaveGuard] }) export class AppRoutingModule { }
guard ディレクトリに新しい product.resolve.ts を作成します。 ProductResolve クラスは Resolve インターフェイスを実装します。
Resolve は、resolve によって解析されるデータのタイプであるパラダイムも宣言する必要があります。
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router"; import { Injectable } from "@angular/core"; import { Observable } from "rxjs/Observable"; import { Product } from "../product/product.component"; @Injectable() export class ProductResolve implements Resolve<Product>{ constructor(private router: Router) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any { let productId: number = route.params["id"]; if (productId == 2) { //正确id return new Product(1, "iPhone7"); } else { //id不是1导航回首页 this.router.navigate(["/home"]); return undefined; } } }
路由配置:Provider里声明,product路由里配置。
resolve是一个对象,对象里参数的名字就是想传入的参数的名字product,用ProductResolve来解析生成。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { ProductComponent } from './product/product.component'; import { Code404Component } from './code404/code404.component'; import { ProductDescComponent } from './product-desc/product-desc.component'; import { SellerInfoComponent } from './seller-info/seller-info.component'; import { ChatComponent } from './chat/chat.component'; import { LoginGuard } from './guard/login.guard'; import { UnsaveGuard } from './guard/unsave.guard'; import { ProductResolve } from './guard/product.resolve'; const routes: Routes = [ { path: '', redirectTo : 'home',pathMatch:'full' }, { path: 'chat', component: ChatComponent, outlet: "aux"},//辅助路由 { path: 'home', component: HomeComponent }, { path: 'product/:id', component: ProductComponent, children:[ { path: '', component : ProductDescComponent }, { path: 'seller/:id', component : SellerInfoComponent } ] , // canActivate: [LoginGuard], // canDeactivate: [UnsaveGuard], resolve:{ //resolve是一个对象 product : ProductResolve //想传入product,product由ProductResolve生成 }}, { path: '**', component: Code404Component } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [LoginGuard,UnsaveGuard,ProductResolve] }) export class AppRoutingModule { }
修改一下product.component.ts 和模版,显示商品id和name。
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; @Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css'] }) export class ProductComponent implements OnInit { private productId: number; private productName: string; constructor(private routeInfo: ActivatedRoute) { } ngOnInit() { // this.routeInfo.params.subscribe((params: Params)=> this.productId=params["id"]); this.routeInfo.data.subscribe( (data:{product:Product})=>{ this.productId=data.product.id; this.productName=data.product.name; } ); } } export class Product{ constructor(public id:number, public name:string){ } }
<p class="product"> <p> 这里是商品信息组件 </p> <p> 商品id是: {{productId}} </p> <p> 商品名称是: {{productName}} </p> <a [routerLink]="['./']">商品描述</a> <a [routerLink]="['./seller',99]">销售员信息</a> <router-outlet></router-outlet> </p>
效果:
点商品详情链接,传入商品ID为2,在resolve守卫中是正确id,会返回一条商品数据。
点商品详情按钮,传入商品ID是3,是错误id,会直接跳转到主页。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がAngular ルート ガードを使用する手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。