Angular4.0学习笔记 从入门到实战打造在线竞拍网站学习笔记之二--路由
Angular4.0基础知识之组件
Angular4.0基础知识之路由
Angular4.0依赖注入
Angular4.0数据绑定&管道
路由
简介
接下来学习路由的相关知识
本来是不准备写下去的,因为当时看视频学的时候感觉自己掌握的不错 ( 这是一个灰常不好的想法 ) ,过了一段时间才发现Angular这个对我这个PHP程序猿来说不太常用的东西非常容易忘!幸好之前去写了笔记。
首先需要先了解一个概念(SPA),也就是单页面应用,一个页面只加载一次,不再刷新,只改变页面部分内容的应用。
路由的作用就是为每一个视图分配一个唯一的URL,进入这个URL的时候,使应用跳到某个特定的视图状态。
创建
在创建项目的时候 , 带上参数ng new RouterDemo --routing即可生成一个带路由文件的项目
Angular路由常见对象
| 名称 | 简介 |
|---|---|
| Routes | 路由的配置,URL和组件之间的映射以及组件和组件插座RouterOutlet的映射关系 |
| RouterOutlet | 在HTML中标记组件插入位置的占位符标签 |
| Router | 在运行时执行路由的对象,navigate()和navigateByUrl()方法导航到指定的路由,使用依赖注入在控制器中获取 |
| RouterLink | 在HTML中声明路由导航的标签属性 |
| ActivatedRoute | 当前激活的路由对象,保存着当前路由的信息,如路由地址参数等,使用依赖注入在控制器中获取 |
在项目中,路由文件通常为app-routing.module.ts
配置
打开路由文件,在routes:Routes对象中定义路由列表,其中,每一个路由至少包含两个参数,即path和component也就是URL和组件的映射关系
注意:这里的
path最好不要以/开头,否则会导致路由URL相对关系的混乱,Angular会自动帮你处理和子路由的关系,除非你明确知道你要做什么
app-routing.module.ts源码
import {NgModule} from '@angular/core'
import {RouterModule, Routes} from '@angular/router';
import {ProductDetailComponent} from './product-detail/product-detail.component';
import {HomeComponent} from './home/home.component';
const routes: Routes = [
{path: '', component: HomeComponent},
{path: 'product/:prodTitle', component: ProductDetailComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: []
})
export class AppRoutingModule {}
app.module.ts修改部分
imports: [
...
AppRoutingModule
...
],
如上,最简单的路由便定义完毕啦
插座
所谓的插座,也就是在HTML中定义的路由对应的组件插入点
使用<router-outlet></router-outlet>标签定义路由对应组件的插入位置(在该标签下面)
路由链接
使用<a [routerLink]=['/product']>商品详情</a>来定义一个路由导航链接
注意这里的路由字符串需要加上
/,后面我们会使用./等来区分路由和子路由
路由的参数是一个数组而不是字符串,因为后面我们需要给路由传递参数
然后我们就可以通过点击商品详情链接来显示product组件的内容了
使用Router对象进行导航
当你定义了一个事件进行跳转的时候,例如:
<input type="button" (click)="toProductInfo()" />
控制器代码
export class AppComponent {
// 使用依赖注入拿到Router对象
constructor(private router:Router){}
// 事件绑定的方法,跳转
toProductInfo() {
this.router.navigate(['/product']);
}
}
即可实现用代码进行路由跳转
默认路由
当输入一个不存在的地址时,路由插座区域无法显示,并且会在控制台抛出异常,我们可以通过定义一个默认路由(例如404page)来避免错误发生
首先,我们生成一个新的组件,运行ng g component code404
生成404页面组件,简单编写内容之后,进入路由配置文件,添加一个新的路由配置信息
...
// 放在最后,当匹配不到的时候会选择此路由
{path:'**',component:Code404Component}
传递参数
传递
| 传递方式 | 形式 | 获取方式 |
|---|---|---|
| 查询参数传递(GET方法) | <a [routerLink]=['/product'] [queryParams]="{id:1}"></a>=>/?id=1&name=jeffrey |
ActivatedRoute.queryParams['id'] |
| 在路由形式中定义参数 | {path:'product/:id'}=><a [routerLink]=['/product/',1]></a>=>/product/1 |
ActivatedRoute.params['id'] |
| 在路由配置中定义静态数据 | {{path:'product/:id',component:ProductComponent,data:[{osProd:true}]}} | ActivatedRoute.data[0]['isProd'] |
获取
在constructor构造函数参数中使用依赖注入获取到ActivatedRoute存入routeInfo变量,在ngOnInit()取出参数
- 直接取出(参数快照)
this.productId=this.routeInfo.snapshort.queryParams['id'] - 关联获取(参数订阅),在同翼哥组件之间路由的时候,由于
ngOnInit()只会执行一次,导致参数不能刷新,这时候可以使用参数订阅来关联地获取到参数。(下面例子使用了箭头函数)
this.routeInfo.params.subscribe((params:Params)=>this.productId=params['id'])
重定向路由
在访问一个特定路由时,重定向到另一个指定地址
例如:
{path: '', redirectTo:'/home',pathMatch:'full'},
{path: 'home', component: HomeComponent},
pathMatch指匹配策略
当我们访问http://127.0.0.1:4200的时候,会自动跳转到http://127.0.0.1:4200/home
子路由
在一个路由的组件中展示其他组件的内容时,使用子路由来实现。
其实更应该理解为“子组件”,也就是一个大的组件里的一部分,使用子路由来控制
在主路由的routerOutlet显示主路由的组件内容时,根据子路由的变化,在主路由组件中子路由对应routerOutlet位置显示对应的子路由组件
辅助路由
形式:<router-outlet name="fuzhu"></router-outlet>
{path:'xxx',component:XxxComponent,outlet:'fuzhu'}
<a [routerLink]=['/home',{outlets:{fuzhu:'xxx'}}]>链接</a>或<a [routerLink]=[{outlets:{primary:'home',fuzhu:'xxx'}}]>链接</a>
当点击链接的时候,主插座会显示home组件的内容,fuzhu插座会显示xxx路由匹配到的Xxx组件
<a [routerLink]=[{outlets:{fuzhu:'xxx'}}]>链接</a>
当点击链接的时候,主插座不变,fuzhu插座会显示xxx路由匹配到的Xxx组件
<a [routerLink]=[{outlets:{fuzhu:null}}]>链接</a>
当点击链接的时候,fuzhu插座不显示任何组件
辅助路由允许你在同一个组件中定义多个插座,并定义每个插座显示的内容
路由守卫
简介
所谓的路由守卫,也就是在满足一定条件的时候才允许进入或退出某一个路由。例如:
- 在用户登录之前,不允许进入个人中心页面
- 在某个表单的执行流程中,只有用户完成了上一步的任务之后,才能进入下一步的环节
- 当用户没有执行保存操作而试图离开某一个路由的时候,阻止离开并进行提示
路由守卫主要有三种类型:
- CanActivate 是否能进入到某个路由
- CanDeactivate 是否能离开某个路由
- Resolve 在路由激活之前获取数据
现在,在路由对象里我们有多了一个新的参数:canActivate,该参数是数组格式,也就是说,一条路由允许接收多个守卫
那么如何编写守卫呢?
canActivate守卫
在src目录中建立一个存放守卫的目录guard,新建路由守卫TypeScript文件,例如login.guard.ts,下面展示一个简单的Demo:
(为了便于演示,不去做真正的登录服务,只是生成一个随机数来判断是否已经登录)
import {canActivate} from "@angular/router";
export class LoginGuard implements CanActivate {
canActivate(){
// 假设随机数小于0.5就代表已经登录
let isLogin:boolean = Math.random()<0.5;
if(!isLogin){
console.log("未登录");
}
return isLogin;
}
}
import {LoginGuard} from "./guard/login.guard";
{path:'product/:id',component:ProductComponent,children:[......],canActivate:[LoginGuard]}
...
@NgModule({
imports:[...],
exports:[...],
providers:[LoginGuard]
})
这样,我们就是先了一个简单的路由守卫,当我们试图导航到这个路由的时候,会判断守卫返回的Boolean值,为True则通过。
!还有这种操作?!在学Angular的时候顺便学了TypeScript~
canDeactivate守卫
同理,我们能很轻易地区是先一个canDeactivate守卫,区别在于canDeactivate守卫在是先接口的时候需要制定一个泛型(也就是需要保护的组件),算了,直接上代码吧:
import {CanDeactivate} from "@angular/router";
import {ProductComponent} from "../product/";
export class UnsavedGuard implements CanDeactivate<ProductComponent>{
/*
需要实现一个方法
因为是需要离开,那么这里需要根据组件里的某些状态来判定
*/
canDeactivate(component:ProductComponent){
return window.confirm("您还没保存,确定要离开吗?");
}
}
Resolve守卫
Resolve守卫常用于解决数据预加载问题,如果使用路由中传递的参数,在进入某一个组件之后发出Http请求去获取所需要的数据,那么在刚进入这个组件的时候,所有使用插值表达式的位置都是空的,这样用户体验会很差。这时候可以使用Resolve守卫来解决,在进入之前先获取数据,进入之后立即使用并显示出来
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {Product} from '../product/product.component';
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';
@Injectable() // 装饰器,允许注入
export class ProductResolve implements Resolve<Product> {
// 注入路由对象
constructor(private router: Router) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Product | Observable<Product> | Promise<Product> {
const productId: number = route.params['id'];
if (productId === 1) {
return new Product(1, '小米6', 2999, 5, '很不错的手机', ['数码'])
} else {
this.router.navigate(['/home']);
return undefined;
}
}
}
在路由中我们有遇到了一个新的参数:resolve,接收一个数组(Resolve守卫)
{path:'product/:id',component:ProductComponent,resolve:{product:ProductResolve}}
同样需要在providers里声明一下。
那么如何取出Resolve守卫传入的数据呢?
同样可以使用参数订阅的方式:
// routeInfo:ActivatedRoute
this.routeInfo.data.subscribe((data:{product:Product})=>{
this.productId=data.product.id;
});
好了,路由的知识点到现在就告一段落,但是Angular的学习之路仍未完待续......
Angular4.0学习笔记 从入门到实战打造在线竞拍网站学习笔记之二--路由的更多相关文章
- Angular4.0从入门到实战打造在线竞拍网站学习笔记之二--路由
Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 Angular4.0数据绑定&管道 路由 简介 接下来学习路由的相关知识 本来是不准备写下 ...
- Angular4.0从入门到实战打造在线竞拍网站学习笔记之一--组件
Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 Angular4.0数据绑定&管道 最近搞到手了一部Angular4的视频教程,这几天正好 ...
- Angular4.0从入门到实战打造在线竞拍网站学习笔记之四--数据绑定&管道
Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 数据绑定 数据绑定允许你将组件控制器的属性和方法与组件的模板连接起来,大大降低了开发时的编码量. ...
- Angular4.0从入门到实战打造在线竞拍网站学习笔记之三--依赖注入
Angular4.0基础知识之组件 Angular4.0基础知识之路由 依赖注入(Dependency Injection) 正常情况下,我们写的代码应该是这样子的: let product = ne ...
- Angular 4 学习笔记 从入门到实战 打造在线竞拍网站 基础知识 快速入门 个人感悟
最近搞到手了一部Angular4的视频教程,这几天正好有时间变学了一下,可以用来做一些前后端分离的网站,也可以直接去打包web app. 环境&版本信息声明 运行ng -v @angular/ ...
- Swoole入门到实战 打造高性能 赛事直播平台(完整版)
Thinkphp+Swoole入门到实战打造高性能赛事直播平台 第1章 课程介绍 欢迎大家来到swoole的课程!本章主要是介绍了swoole的一些特性,以及使用场景,并且分享了swoole在其他公司 ...
- swoole入门到实战打造高性能赛事直播平台☆
第1章 课程介绍 本章主要是介绍了swoole的一些特性,以及使用场景,并且分享了swoole在其他公司的一些案例,最后重点讲解了swoole学习的一些准备工作. 第2章 PHP 7 源码安装 本 ...
- 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程
点击了解更多Python课程>>> 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程 适用人群: 即将毕业的大学生,工资低工作重的白领,渴望崭露头角的职场新人, ...
- 韩天峰力荐 Swoole入门到实战打造高性能赛事直播平台
第1章 课程介绍欢迎大家来到swoole的课程!本章主要是介绍了swoole的一些特性,以及使用场景,并且分享了swoole在其他公司的一些案例,最后重点讲解了swoole学习的一些准备工作.1-1 ...
随机推荐
- django ngRoute ui-router 开发环境下禁用缓存
问题描述: Python manage.py runserver ,禁用缓存,及时修改反馈到浏览器 解决办法: 使用dummy cache: Dummy caching (for developmen ...
- MongoDB--架构搭建(主从、副本集)之主从
此章节讲述主从架构 主从架构 -- 目前已经不建议使用,推荐使用复制集 主从配置可以在配置文件中配置 从节点可以在启动之后使用命令追加主节点,db.source.insert({"host ...
- UIPopoverPresentationController使用
UIPopoverPresentationController是什么? iOS8.0之后引入的一个方便开发者创建带箭头的弹出控制器,类似qq消息页面点击右上角加号弹出的视图. UIPopoverPre ...
- ecshop加入购物车效果(各个页面)
ecshop中点击加入购物车出现下图 通过以下代码改成下图效果 1.后台网店设置 购物车确定提示 选择为“提示用户,点击“确定”进购物车” 2.打开js/common.js 104行就是funct ...
- Java数值避免浮点型计算丢失精度问题
问题描述及方案 假设我们在做电商项目,在进行计算时这个丢失精度在产品价格计算就会出现问题,很有可能造成我们手里有9.99元然后后面会有一堆9,但是呢这些钱无法购买一个10元的商品. 在某些编程语言中有 ...
- 使用 XML 配置 MyBatis
构建 SqlSessionFactory 最常见的方式是基于 XML 配置(的构造方式).下面的 mybatis-config.xml 展示了一个 典型的 MyBatis 配置文件的样子: XML C ...
- phpcms和php格式化时间戳
用PHPCMS V9 建站时,经常会用到时间标签,它是通用标签调用-日期时间格式化,适用全站. 一.日期时间格式化显示: a\标准型:{date('Y-m-d H:i:s', $rs['inputti ...
- H5个性三级联动日期插件(一)
1. 先看效果:如图 2.如果跟你的需求一样的话,那就抓紧down(当)起来吧! 首先你的页面可能需要很多的开发需求文件: jquery,mobiscroll 等js框架插件等 自己参照官方的demo ...
- 大数据 Hadoop,Spark和Storm
大数据(Big Data) 大数据,官方定义是指那些数据量特别大.数据类别特别复杂的数据集,这种数据集无法用传统的数据库进行存储,管理和处理.大数据的主要特点为数据量大(Volume),数据类别复 ...
- JavaScript 语言基础
js语言基础 一 基本知识 UniCode编码 区分大小写(HTML不区分/XHTML区分) Unicode转义序列 \uxxxx (\u加4位16进制表示) 注释 单行注释:// 多行注释:/* * ...