国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解Angular路由之路由守衛

2019-11-19 13:52:48
字體:
來源:轉載
供稿:網友

一、路由守衛

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

路由守衛場景:

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

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

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

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

  1. CanActivate: 處理導航到某路由的情況。
  2. CanDeactivate: 處理從當前路由離開的情況。
  3. 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 }];

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

三、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留在當前頁面。

四、Resolve守衛

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

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

resolve解決辦法:在進入路由之前去服務器讀數據,把需要的數據都讀好以后,帶著這些數據進到路由里,立刻就把數據顯示出來。

實例:

在進入商品信息路由之前,準備好商品信息再進入路由。 拿不到信息,或者拿信息出問題了,直接跳到錯誤信息頁面,或者彈出提示,就不再進入目標路由。

先在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){ }}
<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,會直接跳轉到主頁。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大港区| 额敏县| 延安市| 英吉沙县| 鄄城县| 新沂市| 太湖县| 孝感市| 吴旗县| 中山市| 四会市| 兴宁市| 锦州市| 客服| 清涧县| 金华市| 孟连| 南郑县| 大余县| 米泉市| 武穴市| 五寨县| 文昌市| 灵寿县| 平原县| 格尔木市| 寿宁县| 禄丰县| 隆尧县| 上栗县| 垫江县| 罗城| 义乌市| 舒兰市| 日照市| 芦溪县| 和顺县| 板桥市| 体育| 宝鸡市| 旺苍县|