Angular ルーティングでルーティング ガードを使用する方法

php中世界最好的语言
リリース: 2018-05-30 14:31:57
オリジナル
1785 人が閲覧しました

この記事では、Angular ルーティングのルートガードの詳細な説明を主に紹介していますが、編集者が非常に優れていると考えたので、参考として共有します。編集者をフォローして見てみましょう

1. ルートガード

ユーザーは特定の条件を満たした場合にのみ、ルートへの出入りが許可されます。

ルート ガード シナリオ:

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

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

保存操作を実行せずに現在のナビゲーションを終了しようとすると、ユーザーに警告します。

Angular は、ルートの出入りを制御するためのフックをいくつか提供します。これらのフックはルーティング ガードであり、上記のシナリオはこれらのフックを通じて実現できます。

  1. CanActivate: 特定のルートへのナビゲーションを処理します。

  2. CanDeactivate: 現在のルートからの出発を処理します。

  3. 解決策: ルーティングをアクティブ化する前にルーティング データを取得します。

一部の属性は、ルーティング、パス、コンポーネント、アウトレット、子を構成するときに使用され、ルーティング ガードもルーティング属性です。

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: &#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. 出発時にルートガードを無効化できます

。終了する前に保存するようユーザーに通知します。

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]="[&#39;./&#39;]">商品描述</a>
 <a [routerLink]="[&#39;./seller&#39;,99]">销售员信息</a>
 <router-outlet></router-outlet>
</p>
ログイン後にコピー

效果:

点商品详情链接,传入商品ID为2,在resolve守卫中是正确id,会返回一条商品数据。

点商品详情按钮,传入商品ID是3,是错误id,会直接跳转到主页。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

React怎样在react-router路由实现登陆验证控制

React路由管理与React Router使用详解

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

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