Angular4.0_路由守卫

2023-10-29

路由守卫

只有当用户已经登录并拥有某些权限时,才能进入某些路由。

一个由多个表单组成的向导,例如注册流程,用户只有在当前路由的组件中填写了满足要求的信息才可以导航到下一个路由。

当用户未执行保存操作,而试图离开当前导航时,提醒用户。

  • CanActivate:处理导航到某路由的情况。
  • CanDeactivate:处理当前路由离开的情况。
  • Resolve:在路由激活之前获取路由数据。

下面编写一个伪代码示例

创建登录守卫
创建目录文件guard,在其下面创建login.guard.ts

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

export class LoginGuard implements CanActivate {
    canActivate() {
        let loggedIn: boolean = Math.random() < 0.5;
        if (!loggedIn) {
            console.log("用户未登录");
        }

        return loggedIn;
    }
}

我们模拟的是产生一个随机数,当小于0.5的时候显示,否则log

app-routing.module.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";

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

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

添加登录守卫canActivate:[LoginGuard],注意:我们在这里添加了路由守卫,但是这个canActivate在什么地方被初始化呢?Angular给我们一种依赖注入的方式,在以下的文章会介绍。在这我们只要做一件事,就是在@NgModule的中填写providers:[LoginGuard]

这里写图片描述

接下来我们创建保存守卫在guard文件下创建unSave.guard.ts

import {ProductComponent} from "../product/product.component";
/**
 * Created by mac on 2018/7/24.
 */
export class UnSaveGuard implements CanDeactivate<ProductComponent>{
    canDeactivate(component:ProductComponent){
        return window.confirm("你还没有保存,确定要离开嘛?");
    }
}

这里写图片描述

resolve守卫

在实际开发中,我们会在ngOnInit时,进行网络请求获取数据,展示给用户。但是一般数据没有及时返回的话,页面没有及时渲染,会有不好的用户体验,所以使用resolve守卫,在进行路由跳转之前,获取数据,并由守卫把获取到的数据传递到相应的页面中。

在guard文件目录下创建product.guard.ts

import {Resolve,ActivatedRouteSnapshot, RouterStateSnapshot,Router} from "@angular/router";
import {Observable} from "rxjs";
import {Product} from "../product/product.component";
import {Injectable} from "@angular/core";

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

    constructor(private router:Router){

    }
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product> | Promise<Product> | Product{
        let productId: number = route.params["id"];
        console.log(productId);
        if (productId == 1) {
            return new Product(1,"iPhone7");
        }else {
            this.router.navigate(['/home']);
        }
    }
}

这里的意思是:我传一个id为1的数据时,返回一个新的Product。new Product(1,"iPhone7");如果不是就跳转到首页

product.component.ts

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} 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;
        }
    );
    //参数快照
    // this.productId = this.routeInfo.snapshot.params["id"];
  }

}

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

  }
}

此时我们获取的定义就不是params了,而是data

product.component.html

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

在页面上接收显示productName

app-routing.module.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";
import {ProductResolve} from "./guard/product.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},
    ],resolve:{
        product:ProductResolve
    }
    },
    {path: '**', component: Code404Component},
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
    providers:[LoginGuard,UnSaveGuard,ProductResolve]
})
export class AppRoutingModule {
}

同时把守卫添加进去路由。

app.component.html

<a [routerLink]="['/home']">主页</a>
<!--<a [routerLink]="['/product']" [queryParams]="{id:1}">商品详情</a>-->
<a [routerLink]="['/product',1]">商品详情</a>
<input type="button" value="商品详情" (click)="toProductDetails()">

<a [routerLink]="[{outlets:{primary:'home', aux:'chat'}}]">开始聊天</a>
<a [routerLink]="[{outlets:{aux: null}}]">结束聊天</a>

<router-outlet></router-outlet>
<router-outlet name="aux"></router-outlet>

记得把参数改为1

当我点击商品详情的a标签时,传递参数1,返回productName为iPhone7的Product

这里写图片描述

当我点击商品详情按钮的时候,传递参数为3,直接跳转到首页

这里写图片描述

gitHub参照代码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular4.0_路由守卫 的相关文章

  • 华为OD机试 - 拔河比赛(Java)

    题目描述 公司最近准备进行拔河比赛 需要在全部员工中进行挑选 选拔的规则如下 按照身高优先 体重次优先的方式准备比赛阵容 规定参赛的队伍派出10名选手 请实现一个选拔队员的小程序 输入为一个数组 记录了部门人员的身高 体重信息 如 身高 体
  • linux gz文件合并,快速合并多个fastq.gz文件

    案例描述 需要将Sample test1 R1 fastq gz和Sample test2 R2 fastq gz合并为test fastq gz 操作方法1 先zcat再gzip zcat Sample test 1 R1 fastq g

随机推荐

  • oracle客户端与服务端的连接

    author skate time 2010 08 16 oracle客户端与服务端的连接 参考如下 http blog csdn net wyzxg archive 2010 08 16 5815335 aspx oracle服务进程如何
  • ElasticSearch7.14配置SSL,使用https访问

    ElasticSearch7 14配置SSL 使用https访问 1 生成证书 备注 一定要在es用户中生成证书 1 生成elastic stack ca p12文件 bin elasticsearch certutil ca 2 生成el
  • Validator 用法详解

    validation 用法详解 1 常用注解说明 这是javax validation包中的 主要包括上述的几个注解 注解 描述 AssertFalse 被注释的元素必须为 false AssertTrue 同 AssertFalse De
  • jdbc连接mysql 5.7.17_java jdbc连接mysql报错:No suitable driver found for jdbc

    代码如下 importjava sql publicclassJdbcTest publicstaticvoidmain Stringargs Stringurl jdbc mysql localhost zhoujian Connecti
  • Jeesite4关于权限控制之根据部门公司进行过滤

    在开发中 根据不同的部门或者公司展示相应的数据这种情况是很常见的 但是在jeesite4 中该怎样进行过滤呢 其实在这个方面作者也有考虑 都直接封装好了官方文档请参考 数据权限调用 文档中也明确指出 这个是通过在后台管理系统中 通过打对勾的
  • 基于matlab的大米,大米颗数计算MATLAB软件

    应用背景 大米是人类的主食之一 是稻谷经清理 砻谷 碾米 成品整理等工序后制成的成品 人们购买米大多采用直接称量的方法 市面上也有许多仪器采用光电传感器等方式用于生产加工时米粒的计数 然而这样的方法都比较依赖于设备 不方便人们日常的使用 运
  • 前端mqtt使用总结

    本文转载自https www codenong com cs105863097 主要解决了 mqtt 连接 重连 数据实时传递等问题 简介 MQTT Message Queuing Telemetry Transport 消息队列遥测传输协
  • 电脑网线,网线排序

    网络的使用是越来越普遍 相信不少用户家里的电脑都是使用网线来链接的 当电脑网线不小心被折断了如何来网线排序呢 接下来就来接大家如何来给电脑网线排序 网线排序 双绞线的四对八根导线是有序排列的 对于100M及以上的网络传输速率 每一根线都有定
  • 剪贴板中图片转为BASE64格式

    需求 将图片复制到剪贴板后 希望将图片快捷地转换为BASE64格式 各种在线工具往往需要先将图片保存到本地 然后将本地文件上传 现在考虑将图片保存到本地这一步去掉 直接将图片从剪贴板粘贴到网页的某个元素中 网页触发粘贴事件并获取文件 然后转
  • WebSocket+php实现tail -f 命令的web版本 实时输出日志的增量 web监控log日志

    实现方式是 php的Workerman框架 js的WebSocket PHP workerman 官网地址 可以通过 composer 安装 require walkor workerman 3 5 JS socket WebSocket
  • 数据结构第二版,顺序栈的实现(c语言版)(初始化,入栈,出栈,取栈顶元素 ,遍历)

    include
  • 靶机4 DC-3(过程超详细)

    简介 DC靶场一共有9个 对于学习渗透测试人员 有很大的帮助 是非常不错的靶场 1 下载靶场 靶机名称 DC 3 包含1个flag 下载地址 DC 3 2 VulnHub 2 安装靶场 以DC 1为例 将文件解压 一压缩包形式进行下载 打开
  • 使用DBeaver连接达梦数据库

    下载地址 https dbeaver io download 0 选择类型ODBC 1 下载服务器安装目录的jdbc的jar包 2 编辑驱动设置 上传下载的DmJdbcDriver16 jar 并配置类名与URL模板及端口 3 测试连接 软
  • 浅谈ssm框架分层逻辑

    第一次接触ssm的时候感觉自己就是个无情的码字机器 完全跟着老师敲 每一行代码在干嘛都不是很理解 也经常看到这样的哀嚎 研究了一天后我也算是对这个框架有了一些浅薄的认识 这里我就完全用自己的理解来讲一下 如果说错欢迎指出 ssm Sprin
  • 线程同步和线程死锁

    线程同步 前面刚介绍了有关线程的基本认识 那我们先来思考一个小问题 两个线程之间有没有可能同时对一个资源发起访问呢 答案是肯定 那么在某些情况下这样的同时访问会引发一系列冲突 先来看一个简单的例子 创建两个线程 各自将count增加2500
  • powerdesigner在列表上显示comment的操作

    默认显示选项中没有comment的选项 那么我们就自定义一下 一 自定义comment选项 1 选择菜单 Model gt Extensions 2 插入一行 点击属性 3 鼠标右键点击 Profile 点击 Add Metaclasses
  • Java程序员的福音:Java项目教学之图书管理系统(含源代码)

    1 图书管理系统项目演示 图书管理系统分析 定义Book类 完成主界面和选择 完成查询所有图书 完成添加图书 完成删除图书 完成修改图书 使用Debug追踪调试 2 图书管理系统之标准Book类 我们发现每一本书都有书名和价格 定义一个Bo
  • 京东一面:MySQL 中的 distinct 和 group by 哪个效率更高?

    先说大致的结论 完整结论在文末 在语义相同 有索引的情况下group by和distinct都能使用索引 效率相同 在语义相同 无索引的情况下 distinct效率高于group by 原因是distinct 和 group by都会进行分
  • 【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL源码分析

    一 环境介绍 RK3588主板搭载Android12操作系统 内核是Linux5 10 使用ST的六轴传感器LSM6DSR芯片 二 芯片介绍 LSM6DSR是一款加速度和角速度 陀螺仪 六轴传感器 还内置了一个温度传感器 该芯片可以选择I2
  • Angular4.0_路由守卫

    路由守卫 只有当用户已经登录并拥有某些权限时 才能进入某些路由 一个由多个表单组成的向导 例如注册流程 用户只有在当前路由的组件中填写了满足要求的信息才可以导航到下一个路由 当用户未执行保存操作 而试图离开当前导航时 提醒用户 CanAct