中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular中路由守衛的使用示例

發布時間:2021-02-20 09:48:57 來源:億速云 閱讀:288 作者:小新 欄目:web開發

這篇文章主要介紹了Angular中路由守衛的使用示例,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

一、路由守衛

當用戶滿足一定條件才被允許進入或者離開一個路由。

路由守衛場景:

只有當用戶登錄并擁有某些權限的時候才能進入某些路由。

一個由多個表單組成的向導,例如注冊流程,用戶只有在當前路由的組件中填寫了滿足要求的信息才可以導航到下一個路由。

當用戶未執行保存操作而試圖離開當前導航時提醒用戶。

Angular提供了一些鉤子幫助控制進入或離開路由。這些鉤子就是路由守衛,可以通過這些鉤子實現上面場景。

  • CanActivate: 處理導航到某路由的情況。

  • CanDeactivate: 處理從當前路由離開的情況。

  • Resolve: 在路由激活之前獲取路由數據。

配置路由時候用到一些屬性,path, component, outlet, children, 路由守衛也是路由屬性。

二、CanActivate

實例:只讓登錄用戶進入產品信息路由。

新建guard目錄。目錄下新建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;
    }
}

配置product路由。先把LoginGuard加入providers,在指定路由守衛。

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 }
];

效果:點商品詳情鏈接控制臺會提醒用戶未登錄,不能進入商品詳情路由。

Angular中路由守衛的使用示例

三、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('你還沒有保存,確定要離開嗎?');
    }
}

配置路由,同樣先加到provider,再配置路由。

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離開當前頁面,cancel留在當前頁面。

Angular中路由守衛的使用示例

四、Resolve守衛

http請求數據返回有延遲,導致模版無法立刻顯示。

數據返回之前模版上所有需要用插值表達式顯示某個controller的值的地方都是空的。用戶體驗不好。

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;
        }
    }
}

路由配置: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){
  }
}
<div class="product">
  <p>
    這里是商品信息組件
  </p>
  <p>
    商品id是: {{productId}}
  </p>
  <p>
    商品名稱是: {{productName}}
  </p>
  
  <a [routerLink]="['./']">商品描述</a>
  <a [routerLink]="['./seller',99]">銷售員信息</a>
  <router-outlet></router-outlet>
</div>

效果:

點商品詳情鏈接,傳入商品ID為2,在resolve守衛中是正確id,會返回一條商品數據。

點商品詳情按鈕,傳入商品ID是3,是錯誤id,會直接跳轉到主頁。

Angular中路由守衛的使用示例Angular中路由守衛的使用示例

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Angular中路由守衛的使用示例”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永新县| 都江堰市| 陇川县| 西乌珠穆沁旗| 乐亭县| 手游| 延安市| 桂平市| 乐清市| 新疆| 塔城市| 西林县| 池州市| 罗平县| 乐清市| 鹤峰县| 黄龙县| 望奎县| 隆昌县| 榆林市| 赞皇县| 长乐市| 嵊泗县| 商水县| 桃江县| 宜宾县| 汉寿县| 铅山县| 霍林郭勒市| 浠水县| 朝阳市| 靖边县| 安陆市| 泽库县| 渝北区| 沈阳市| 兴义市| 新沂市| 濮阳市| 乌鲁木齐市| 荣成市|