欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Angular路由之路由守衛(wèi)

 更新時間:2018年05月10日 16:26:23   作者:starof  
這篇文章主要介紹了詳解Angular路由之路由守衛(wèi),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

一、路由守衛(wèi)

當(dāng)用戶滿足一定條件才被允許進(jìn)入或者離開一個路由。

路由守衛(wèi)場景:

只有當(dāng)用戶登錄并擁有某些權(quán)限的時候才能進(jìn)入某些路由。

一個由多個表單組成的向?qū)?,例如注冊流程,用戶只有在?dāng)前路由的組件中填寫了滿足要求的信息才可以導(dǎo)航到下一個路由。

當(dāng)用戶未執(zhí)行保存操作而試圖離開當(dāng)前導(dǎo)航時提醒用戶。

Angular提供了一些鉤子幫助控制進(jìn)入或離開路由。這些鉤子就是路由守衛(wèi),可以通過這些鉤子實現(xiàn)上面場景。

  1. CanActivate: 處理導(dǎo)航到某路由的情況。
  2. CanDeactivate: 處理從當(dāng)前路由離開的情況。
  3. Resolve: 在路由激活之前獲取路由數(shù)據(jù)。

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

二、CanActivate

實例:只讓登錄用戶進(jìn)入產(chǎn)品信息路由。

新建guard目錄。目錄下新建login.guard.ts。

LoginGuard類實現(xiàn)CanActivate接口,返回true或false,Angular根據(jù)返回值判斷請求通過或不通過。

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,在指定路由守衛(wèi)。

canActivate可以指定多個守衛(wèi),值是一個數(shù)組。

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

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

三、CanDeactivate

離開時候的路由守衛(wèi)。提醒用戶執(zhí)行保存操作后才能離開。

在guard目錄下新建一個unsave.guard.ts的文件。

CanDeactivate接口有一個范型,指定當(dāng)前組件的類型。

CanDeactivate方法第一個參數(shù)就是接口指定的范型類型的組件,根據(jù)這個要保護(hù)的組件的狀態(tài),或者調(diào)用方法來決定用戶是否能夠離開。

import { CanDeactivate } from "@angular/router";
import { ProductComponent } from "../product/product.component";

export class UnsaveGuard implements CanDeactivate<ProductComponent>{
  //第一個參數(shù) 范型類型的組件
  //根據(jù)當(dāng)前要保護(hù)組件 的狀態(tài) 判斷當(dāng)前用戶是否能夠離開
  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離開當(dāng)前頁面,cancel留在當(dāng)前頁面。

四、Resolve守衛(wèi)

http請求數(shù)據(jù)返回有延遲,導(dǎo)致模版無法立刻顯示。

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

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

實例:

在進(jìn)入商品信息路由之前,準(zhǔn)備好商品信息再進(jìn)入路由。 拿不到信息,或者拿信息出問題了,直接跳到錯誤信息頁面,或者彈出提示,就不再進(jìn)入目標(biāo)路由。

先在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類實現(xiàn)了Resolve接口。

Resolve也要聲明一個范型,范型就是resolve要解析出來的數(shù)據(jù)的類型。

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導(dǎo)航回首頁
      this.router.navigate(["/home"]);
      return undefined;
    }
  }
}

路由配置:Provider里聲明,product路由里配置。

resolve是一個對象,對象里參數(shù)的名字就是想傳入的參數(shù)的名字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守衛(wèi)中是正確id,會返回一條商品數(shù)據(jù)。

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論