angular知识点--路由(二)路由守卫

碎碎念:知识点梳理归纳,如果有什么不对的感谢大家指正一起学习!

一、路由守卫

当用户满足一些条件的时候才会被允许进入或者离开一些路由

  1. canActivate :处理导航到某路由的情况
    当满足导航到此路由的条件时才允许进入路由

  2. canDeactivate:处理从当前路由离开的情况
    当不满足导航离开路由的条件时不允许离开路由

  3. resolve:在路由激活之前获取路由数据
    在进入路由时就可以立刻把数据展示给用户

1. canActivate

例:判断当用户是否登录才能进入产品信息路由
(模拟登陆:当随机数小于0.5时为登陆状态)

第一步:创建拦截守卫

// 新建的LoginGuard 文件,实现框架CanActivate 接口

import { CanActivate } from '@angular/router';

export class LoginGuard implements CanActivate {

    canActivate() {
        let isLogin = Math.random() < 0.5;
        if(!isLogin){
            console.log("大于0.5,未登陆")
        }
        return isLogin             //返回一个boolean值
    }

}

第二步:在路由配置中添加canActivate属性,并在providers中声明
(加在产品信息路由上)

const routes: Routes = [
  {
    path: 'product/:id', component: ProductComponent,
    children: [
      { path: '', component: ProductDescComponent },
      { path: 'seller/:id', component: SellerInfoComponent }
    ],
    canActivate:[LoginGuard]             // 接收一个数组,可以接受多个路由守卫
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[LoginGuard]
})

canActivate:[LoginGuard] :当应用视图进入此路由时,里面的守卫会被依次调用,只要有一个守卫返回false,路由请求会被拒绝

效果预览:

在这里插入图片描述
打开页面在主页home页,我们在进入商品详情1的时候就会进行验证,如果守卫中的随机数大于0.5会跳转失败,并在控制台打印提示信息。如果小于0.5就成功进入商品详情页。


2. canDeactivate

例:用户离开当前路由时提示是否离开

第一步:创建离开守卫文件

// 新建的UnSaveGuard 文件,实现框架CanDeactivate 接口

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

export class UnSaveGuard implements CanDeactivate<ProductComponent> {
    canDeactivate(component: ProductComponent) {
        return window.confirm("还未保存,确定离开?")
    }
}

CanDeactivate有个一泛型,泛型是指定当前组件类型(要保护的组件类型)。
第一个参数泛型类型的组件(把要保护的组件信息传进来)

第二步:在路由配置中添加canDeactivate属性,并在providers中声明
(加在产品信息路由上)

const routes: Routes = [
  {
    path: 'product/:id', component: ProductComponent,
    children: [
      { path: '', component: ProductDescComponent },
      { path: 'seller/:id', component: SellerInfoComponent }
    ],
    canDeactivate:[UnsaveGuard]       // 接收一个数组,可以接受多个路由守卫
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[UnsaveGuard]
})

效果预览:

在这里插入图片描述
从home页成功进入‘商品详情1’的路由后,从商品详情离开会弹出提示是否离开


3. resolve

resolve守卫在进入路由之前可以预先去服务器上读数据,把需要的数据在进入路由之前读取到,带着数据进入路由并显示(例如插值表达式的值)
使用resolve守卫也可以向路由传递数据

模拟案例:在进入商品信息的路由之前先读取商品信息,读好之后,带着信息进入路由

第一步:创建守卫


@Injectable()
export class ProductRsolve implements Resolve<Product> {     

//Product 声明的泛型,resolve要解析出来的数据类型

    constructor(
        private router: Router
    ) { }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

        let productId = route.params['id'];     // 拿到传进来的商品Id
        if (productId == 1) {
            return new Product(1, '电风扇');
        } else {
            this.router.navigate(['/home']);
            return undefined;
        }
    }
}

要加@Injectable()装饰器<font siz='2">component不用加是因为自身已经集成了

当进入商品的路由时,商品id=1的时候,返回一个:Id是1,详情是电风扇的对象,
如果不是1的话就路由到home组件路由上

*在product.ts中创建Product类

// Product类
export class Product {
  constructor(
    public id: number,
    public name: string
  ) { }
}

第二步:添加到路由配置中

const routes: Routes = [
  {
    path: 'product/:id', component: ProductComponent,
    children: [
      { path: '', component: ProductDescComponent },
      { path: 'seller/:id', component: SellerInfoComponent }
    ],
   resolve: { product: ProductRsolve }
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[ProductRsolve]
})

这里的resolve是一个对象,参数的名字就是想传入的参数名称

product: ProductRsolve(product由ProductRsolve守卫来生成)

第三步:在页面上接收值

// product.ts

export class ProductComponent implements OnInit {

  productId: number;
  productName: string;

  constructor(
    private activatedRoute: ActivatedRoute
  ) { }

  ngOnInit() {
    this.activatedRoute.params.subscribe((params: Params) => this.productId = params["id"]);
    this.activatedRoute.data.subscribe((data: { product: Product }) => {      // 订阅传进来的数据
      this.productId = data.product.id;           //把传进来的id和name赋给本地变量
      this.productName = data.product.name;
    })
  }

}

export class Product {
  constructor(
    public id: number,
    public name: string
  ) { }

}

效果预览:
在这里插入图片描述
从home页链接到商品详情1的时候,id=1所以显示了商品id=1,name是电风扇。再链接到商品详情2的时候id=2,路由直接跳到了home组件上。

总结:在进入组件之前把组件所需要的的数据加载好,拿数据或者出错了就不在进入目标路由

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值