Angular のルーティング ガードの詳細な説明

青灯夜游
リリース: 2021-02-22 17:56:00
転載
1884 人が閲覧しました

この記事では、Angular ルーティングのルーティング ガードを紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

Angular のルーティング ガードの詳細な説明

関連する推奨事項: 「angular チュートリアル

1. ルーティング ガード

ユーザーは特定の条件を満たした場合にのみ、 ルートに入る、または からルートを離れることができます。

ルート ガード シナリオ:

ユーザーがログインし、特定の権限を持っている場合にのみ、特定のルートに入ることができます。

登録プロセスなどの複数のフォームで構成されるウィザード。ユーザーは、現在のルートのコンポーネントに必要な情報を入力した場合にのみ、次のルートに移動できます。

ユーザーが保存操作を実行せずに現在のナビゲーションを離れようとした場合に、ユーザーに通知します。

Angular は、ルートの出入りを制御するための

フック を提供します。これらのフックはルーティング ガードであり、上記のシナリオはこれらのフックを通じて実現できます。

    CanActivate: ルートへのナビゲーションを処理します。
  • CanDeactivate: 現在のルートからの離脱を処理します。
  • 解決策: ルーティングをアクティブ化する前にルーティング データを取得します。
一部の属性は、ルーティング、パス、コンポーネント、アウトレット、子、ルーティング ガードを構成するときに使用されます。また、ルーティング ガードもルーティング属性です。

2. CanActivate

例: ログイン ユーザーのみに製品情報ルーティングへの入力を許可します。

新しいガード ディレクトリを作成します。ディレクトリに新しいlogin.guard.tsを作成します。

LoginGuard クラスは CanActivate インターフェイスを実装し、true または false を返します。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: &#39;&#39;, redirectTo : &#39;home&#39;,pathMatch:&#39;full&#39; }, 
  { path: &#39;chat&#39;, component: ChatComponent, outlet: "aux"},//辅助路由
  { path: &#39;home&#39;, component: HomeComponent },
  { path: &#39;product/:id&#39;, component: ProductComponent, children:[
    { path: &#39;&#39;, component : ProductDescComponent },
    { path: &#39;seller/:id&#39;, component : SellerInfoComponent }
  ] ,canActivate: [LoginGuard]},
  { path: &#39;**&#39;, component: Code404Component }
];
ログイン後にコピー

効果: 製品詳細リンクをクリックすると、コンソールはユーザーに、ログインしていないため製品詳細ルートに入ることができないことを通知します。

#3.CanDeactivate 出発時のルートガード。終了する前に保存するようユーザーに通知します。

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(&#39;你还没有保存,确定要离开吗?&#39;);
    }
}
ログイン後にコピー

ルーティングを構成するには、まずプロバイダーに追加してから、ルーティングを構成します。

import { NgModule } from &#39;@angular/core&#39;;
import { Routes, RouterModule } from &#39;@angular/router&#39;;
import { HomeComponent } from &#39;./home/home.component&#39;;
import { ProductComponent } from &#39;./product/product.component&#39;;
import { Code404Component } from &#39;./code404/code404.component&#39;;
import { ProductDescComponent } from &#39;./product-desc/product-desc.component&#39;;
import { SellerInfoComponent } from &#39;./seller-info/seller-info.component&#39;;
import { ChatComponent } from &#39;./chat/chat.component&#39;;
import { LoginGuard } from &#39;./guard/login.guard&#39;;
import { UnsaveGuard } from &#39;./guard/unsave.guard&#39;;

const routes: Routes = [
  { path: &#39;&#39;, redirectTo : &#39;home&#39;,pathMatch:&#39;full&#39; }, 
  { path: &#39;chat&#39;, component: ChatComponent, outlet: "aux"},//辅助路由
  { path: &#39;home&#39;, component: HomeComponent },
  { path: &#39;product/:id&#39;, component: ProductComponent, children:[
    { path: &#39;&#39;, component : ProductDescComponent },
    { path: &#39;seller/:id&#39;, component : SellerInfoComponent }
  ] ,canActivate: [LoginGuard],
     canDeactivate: [UnsaveGuard]},
  { path: &#39;**&#39;, component: Code404Component }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [LoginGuard,UnsaveGuard]
})
export class AppRoutingModule { }
ログイン後にコピー

効果:

[OK]をクリックして現在のページを離れ、キャンセルして現在のページに留まります。

4. ガードの解決http リクエスト データを返すのに遅延があり、その結果、テンプレートがすぐに表示されない。

データが返される前は、コントローラーの値を表示するために補間式を使用する必要があるテンプレート上のすべての場所が空になっています。ユーザーエクスペリエンスは良くありません。

resolve 解決策: ルーティングを入力する前にサーバーにアクセスしてデータを読み取ります。必要なデータをすべて読み取った後、データを含むルーティングを入力し、すぐにデータを表示します。

例:

製品情報のルーティングを入力する前に、製品情報を準備してからルーティングを入力します。

情報を取得できない場合、または情報の取得に問題がある場合は、エラー メッセージ ページに直接ジャンプするか、プロンプトがポップアップ表示され、目的のルートに入ることはできません。

まず、product.component.ts で製品情報の型を宣言します。

export class Product{
  constructor(public id:number, public name:string){
  }
}
ログイン後にコピー

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;
        }
    }
}
ログイン後にコピー

ルーティング構成: プロバイダーで宣言され、製品ルーティングで構成されます。

resolve はオブジェクトです。オブジェクト内のパラメータの名前は、渡したいパラメータの名前です。それを解析して生成するために Product が使用されます。

import { NgModule } from &#39;@angular/core&#39;;
import { Routes, RouterModule } from &#39;@angular/router&#39;;
import { HomeComponent } from &#39;./home/home.component&#39;;
import { ProductComponent } from &#39;./product/product.component&#39;;
import { Code404Component } from &#39;./code404/code404.component&#39;;
import { ProductDescComponent } from &#39;./product-desc/product-desc.component&#39;;
import { SellerInfoComponent } from &#39;./seller-info/seller-info.component&#39;;
import { ChatComponent } from &#39;./chat/chat.component&#39;;
import { LoginGuard } from &#39;./guard/login.guard&#39;;
import { UnsaveGuard } from &#39;./guard/unsave.guard&#39;;
import { ProductResolve } from &#39;./guard/product.resolve&#39;;

const routes: Routes = [
  { path: &#39;&#39;, redirectTo : &#39;home&#39;,pathMatch:&#39;full&#39; }, 
  { path: &#39;chat&#39;, component: ChatComponent, outlet: "aux"},//辅助路由
  { path: &#39;home&#39;, component: HomeComponent },
  { path: &#39;product/:id&#39;, component: ProductComponent, children:[
    { path: &#39;&#39;, component : ProductDescComponent },
    { path: &#39;seller/:id&#39;, component : SellerInfoComponent }
  ] ,
    //  canActivate: [LoginGuard],
    //  canDeactivate: [UnsaveGuard],
    resolve:{ //resolve是一个对象
      product : ProductResolve   //想传入product,product由ProductResolve生成
    }},
  { path: &#39;**&#39;, component: Code404Component }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [LoginGuard,UnsaveGuard,ProductResolve]
})
export class AppRoutingModule { }
ログイン後にコピー

product.component.ts とテンプレートを変更して、製品 ID と名前を表示します。

import { Component, OnInit } from &#39;@angular/core&#39;;
import { ActivatedRoute, Params } from &#39;@angular/router&#39;;

@Component({
  selector: &#39;app-product&#39;,
  templateUrl: &#39;./product.component.html&#39;,
  styleUrls: [&#39;./product.component.css&#39;]
})
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){
  }
}
ログイン後にコピー
<div class="product">
  <p>
    这里是商品信息组件
  </p>
  <p>
    商品id是: {{productId}}
  </p>
  <p>
    商品名称是: {{productName}}
  </p>
  
  <a [routerLink]="[&#39;./&#39;]">商品描述</a>
  <a [routerLink]="[&#39;./seller&#39;,99]">销售员信息</a>
  <router-outlet></router-outlet>
</div>
ログイン後にコピー

効果:

製品詳細リンクをクリックし、製品 ID を 2 (解決ガード内の正しい ID) として渡すと、製品データの一部が返されます。

製品の詳細ボタンをクリックすると、受信した製品 ID は 3 ですが、これは間違った ID であり、ホームページに直接ジャンプします。

この記事は http://www.cnblogs.com/starof/p/9012193.html

から転載しています。

プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !

以上がAngular のルーティング ガードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート