angular路由守卫

   路由守卫是指当用户满足了某些要求之后才可以离开或者进入某个页面或者场景的时候使用。比如说只有当用户填写了用户名和密码之后才可以进入首页,比如说用户离开某个页面时明月保存信息提示用户是否保存信息后再离开等操作,控制这些要求的就叫路由守卫。

 1.CanActivate 进入路由守卫(通俗来说:创建一个守卫,将要求写入守卫里面,将守卫注入到使用的页面,在路由里面引用这个守卫,)

这种守卫是指用户必须满足某些要求后才可以进入路由。比如注册登录

1.首先建立一个守卫文件guard,在文件里面建一个守卫guard.ts

2.在guard.ts里面定义一个类,这个类实现一个接口CanActivate:这个接口只有一个方法就是canActivate(){}

这个方法返回一个布尔值true或者是false,来决定是否进入路由;

 

import {CanActivate} from "@angular/router";
export  class  LoginGard implements CanActivate{
  canActivate(){
    let loggedIn:boolean=Math.random()<0.5;
    if(!loggedIn){
      console.log("用户未登录");
    }
    return loggedIn;
  }
}

 

3.接下来去配置路由:在配置路由的时候呢在路由后面加一个canActivate属性,这个属性的值是一个数组,可以是多个值,这里的多个值是所有路由的守卫,也就是说该路由需要满足的路由守卫有哪些,路由会依次调用这些守卫,只有当满足所有守卫的要求时路由才有效,也就是所有守卫的返回值都为true的时候才可以同过路由守卫。

 

4.路由配置好了之后需要利用依赖注入来实现这个类。

 

import {LoginGard} from "./gard/login.gard";
 

 

const routes:Routes=[
  {path:'',redirectTo:'/home',pathMatch:'full'},
  {path:'chat',component:XhatComponent,outlet:'aux'},
  {path:'product',component:ProductComponent,children:[
    {path:'',component:ProductdescComponent} ,
    {path:'seller/:id',component:SellerComponent}
  ],canActivate:[LoginGard]},
  {path:'home/:id',component:HomeComponent},//整个路径被划分成两段变量,一段是路径,一段时参数
  {path:'**',component:Code404Component}
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports:[RouterModule],
  providers: [LoginGard]
})
export class AppRoutingModule { }

 

2.CanDeactivate 离开路由守卫

这种守卫是指用户如果不能满足当前守卫的要求就不能离开此页面

  1,同CanActivate一样首先也要顶一个守卫这个守卫实现一个接口CanDeactivate ,不一样的是这个接口要实现一个泛型,这个泛型就是指定当前组件的类型,即要守护的组件;

 2.这个接口有一个canDeactivate()的方法,一样要接受一个参数,这个参数是当前保护的组件的参数信息;用这些信息来判断满足什么样的条件方可离开此组件页面

 

import {CanDeactivate} from "@angular/router";
import {ProductComponent} from "app/product/product.component";
export  class  UnsaveGuard implements CanDeactivate<ProductComponent>{
  canDeactivate(component: ProductComponent){
     return window.confirm("您还没有保存确定要离开吗")//如果用户点否就继续留在本页面,点确定才会离开本页面。window.confirm弹出一个弹框
  }

}
 3.配置路由,和canActivate一样的配置方式

 

 

const routes:Routes=[
  {path:'',redirectTo:'/home',pathMatch:'full'},
  {path:'chat',component:XhatComponent,outlet:'aux'},
  {path:'product',component:ProductComponent,children:[
    {path:'',component:ProductdescComponent} ,
    {path:'seller/:id',component:SellerComponent}
  ],canActivate:[LoginGard],
    canDeactivate:[UnsaveGuard]
},

 

 

 

3.Resolve 激活路由守卫(通俗来说就是首先创建一个路由守卫来提前获取组件参数值,其次将参数值再返回给组件视图);
这种守卫在路由激活前触发,一般用来获取激活路由对应视图组件数据使用。
进入视图前,利用该守卫将视图所需数据加载完成,
可以避免网络不好的时候用户进入视图后网络不好造成数据加载不出来的情况出现,
此路由守卫在加载视图前请求好数据后才进入视图。
同样的1.创建一个路由守卫实现一个接口Resolve,这个接口接受一个泛型,这个泛型
是该守卫要解析出来的数据的结构和类型。
2.实现一个resolve方法,这个方法可以获取路由携带的参数,获取到参数后才可以进
入视图。

import {Injectable} from "@angular/core";
export class  ProductRsolve implements  Resolve<Product>{//这个product泛型类需要自己定义一下引入
  @Injectable()//只有加这个装饰器router才可以被注入进来
  constructor(private router:Route){
  }
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Product | Observable<Product> | Promise<Product> {//这里的ActivatedRouteSnapshot可以直接获取路由里面的参数,因此接下来就可以直接获取参数值

     let productId:number=Route.params["id"];//Route.params直接获取参数
    if(productId==1){
      return new Product(1,"iphnoe7");
    }else {
      this.router.navigate(["/home"]);//注入router后才可以使用导航
    }
  }

}

export class Product{
  constructor(public id:number,public name:string){
  }
3.配置路由不一样的是路由里面resolve接收的是一个对象,这个对象的name就是守卫要接受的参数,值就是用哪个守卫来解析这个name。
4.和其他守卫一样也需要注入

const routes:Routes=[
  {path:'',redirectTo:'/home',pathMatch:'full'},
  {path:'chat',component:XhatComponent,outlet:'aux'},
  {path:'product',component:ProductComponent,children:[
    {path:'',component:ProductdescComponent} ,
    {path:'seller/:id',component:SellerComponent}
  ],resolve:{
    product:ProductRsolve
  }
在组件中定义变量接收参数

export class ProductComponent implements OnInit {
  routerInfo: any;
  private productId:number;//定义两个参数来接收路由传进来的值
  private productName:string;

  constructor(private routerIonfo:ActivatedRoute) { }

    ngOnInit() {
      this.productId=this.routerIonfo.snapshot.queryParams["id"];
      this.routerInfo.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){
  }
}
原文地址:https://www.cnblogs.com/dalulu/p/8743412.html