angular4、angular4.0从入门到实战 打造股票管理网站 1.子路由 2. 路由传参三种方式 3. 路由守卫
2017-07-30 16:47
633 查看
可能有点语无伦次。。。。。因为第一次写这么长的博文~~~
最近跳入了angular4的坑,之前看的angular权威教程是angularJS1.的版本,之后的angular2和angular4改动非常大,可以说是两个框架了(雷锋和雷峰塔),google公司只对angularJS1.维护两年,所以果断弃了angularJS,现在大多是angular2和angular4应用居多 锤子科技官网http://www.smartisan.com/#/shop就是用angular4写的,现在学到了路由,跟着视频过了一遍,然后又自己写一遍代码加深记忆,视频是慕课网出的angular4.0从入门到实战 打造股票管理网站 有需要的小伙伴可以留言 路由这一章课程有三个小例子,spa (single page application)单页面应用,路由真的炒鸡有用啊感觉, 才接触angular我想记录下来因为忘的炒鸡快啊衰,环境搭建的时候有各种错误 搞得心累 要装node,angularCli npm 环境搭建这里有问题也可以留言因为我真的碰到好多问题!!!! 我用的是webstorm2017.2 这个博文内容比较杂,有时间分开一下 这样不好找,内容大概有
子路由
路由传参三种方式
路由守卫
我会放截图还有需要注意的地方
先说一下流程(环境搭建就不说了,网上有很多教程博文)
1.创建项目 ng new myrouter –routing
/———后面的–routing必须加上,才会生成路由配置文件,我下面那个图里可以看到app-routing-modules.ts———/
2.npm install jquery –save (两个横线!)
npm install bootstrap –save
npm install @types/jquery –save-dev
npm install @types/bootstrap –save-dev
(后面这两个也要装上,因为angular是typescript写的,而这两个库
javascript~~大概是因为这个)
3.接下来就是添加你要用的组件了
ng g component home
ng g component product
ng g component code404
4.准备工作都做好了,现在开始码代码~
app.component.html
标签必须有,这相当于插座,让待显示的组件的内容知道放到哪里," title="">
home.component.html
product.component.html
组件里的内容可以自由构思,接下来就是路由配置了
在app-routing.modules.ts里配置,只需要修改Routes里内容即可,
这个意思就是一进入页面就跳转显示指定的home组件的内容,这个可以自己指定,path不能以斜杠(/)开头。 路由器会为解析和构建最终的URL,这样当我们在应用的多个视图之间导航时,可以任意使用相对路径和绝对路径。路由的定义顺序是刻意如此设计的。路由器使用先匹配者优先的策略来匹配路由,所以,具体路由应该放在通用路由的前面。在上面的配置中,带静态路径的路由被放在了前面,后面是空路径路由,因此它会作为默认路由。而通配符路由被放在最后面,这是因为它能匹配上每一个URL,因此应该只有在前面找不到其它能匹配的路由时才匹配它。
这两行代码,第一行是常规指定路径的方法,一般在输入ProductComponent时会自动在文件前面添加import{…},alt+enter就可以添加 我下载的webstorm没有自己配置,如果设置快捷键了就按自己的,,第二行path路径是通配符,意思就是如果用户输入的路径不存在就会显示指定的组件Code404Component
首先添加一个 product-desc组件,编辑对应的html文件,想让这个组件在product组件下显示,所以正题来了。。。。
1. product.html
标签必须写,routerLink是一个数组,后面的数字是传入的参数,子路由是./
2.配置路由,如果要传入参数记得格式path:’desc/:id’ id是自定义的
3.到这一步已经实现了子路由,对于传进去的参数可以获取到
因为是给子路由传递的参数,所以在product-desc.component.html
product-desc.component.ts
这样就可以在路由到product-desc时页面上就会显示productId
传递参数的方法有三种,一种是上面提到的在路径中传递,还有一种是在查询参数中传递 代码如下
product.component.html
配置路径这里:
product-desc.component.html
第三种方式:在路由配置中添加静态数据传递参数
路由配置:
获取 :data[0][‘id’]表示获取路由参数中第一个对象的id属性
product.component.html
看一下angular4中文社区对路由守卫的描述
上面的例子,用户都能在任何时候导航到任何地方。 但有时候这样是不对的。
该用户可能无权导航到目标组件。
可能用户得先登录(认证)。
在显示目标组件前,我们可能得先获取某些数据。
在离开组件前,我们可能要先保存修改。
我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?
我们可以往路由配置中添加守卫,来处理这些场景。守卫返回一个值,以控制路由器的行为:
如果它返回true,导航过程会继续
如果它返回false,导航过程会终止,且用户会留在原地。
守卫还可以告诉路由器导航到别处,这样也取消当前的导航。
守卫可以用同步的方式返回一个布尔值。但在很多情况下,守卫无法用同步的方式给出答案。 守卫可能会向用户问一个问题、把更改保存到服务器,或者获取新数据,而这些都是异步操作。
因此,路由的守卫可以返回一个Observable或Promise,并且路由器会等待这个可观察对象被解析为true或false。
路由器支持多种守卫:
用CanActivate来处理导航到某路由的情况。
用CanActivateChild处理导航到子路由的情况
用CanDeactivate来处理从当前路由离开的情况。
用Resolve在路由激活之前获取路由数据。
用CanLoad来处理异步导航到某特性模块的情况。
在分层路由的每个级别上,我们都可以设置多个守卫。 路由器会先按照从最深的子路由由下往上检查的顺序来检查CanDeactivate()和CanActivateChild()守卫。 然后它会按照从上到下的顺序检查CanActivate()和CanActivateChild()守卫。 如果特性模块是异步加载的,在加载它之前还会检查CanLoad()守卫。 如果任何一个守卫返回false,其它尚未完成的守卫会被取消,这样整个导航就被取消了。
这一章介绍三个路由守卫
1.canactivate:要求认证
应用程序通常会根据访问者来决定是否授予某个特性区的访问权。 我们可以只对已认证过的用户或具有特定角色的用户授予访问权,还可以阻止或限制用户访问权,直到用户账户激活为止。
CanActivate守卫是一个管理这些导航类业务规则的工具。
CanActivate:[] 接收一个数组,可以指定多个路由守卫,当视图进入此路由时,所有守卫会被依次调用,如果有一个守卫返回false,则路由请求会被拒绝掉,看一下步骤
a.创建一个directive文件夹名为guard
b.在此文件夹下建一个typescript文件,命名为login.guard.ts
c.编写login.guard.ts
d.配置路由,可以添加多个守卫
e.路由配置文件里要添加providers
我测试了一下,对一个组件添加多个守卫,给上一个home组件按照同样的步骤添加一个test.ts ,让这个守卫返回false,果然home这个组件就没法加载出来
test.ts
2.来说下CanDeactivate 处理未保存的更改
在现实世界中,我们得先把用户的改动积累起来。 我们可能不得不进行跨字段的校验,可能要找服务器进行校验,可能得把这些改动保存成一种待定状态,直到用户或者把这些改动作为一组进行确认或撤销所有改动。
当用户要导航到外面时,该怎么处理这些既没有审核通过又没有保存过的改动呢? 我们不能马上离开,不在乎丢失这些改动的风险,那显然是一种糟糕的用户体验。
我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。
在保存成功之前,我们还可以继续推迟导航。如果我们让用户立即移到下一个界面,而保存却失败了(可能因为数据不符合有效性规则),我们就会丢失该错误的上下文环境。
在等待服务器的答复时,我们没法阻塞它 —— 这在浏览器中是不可能的。 我们只能用异步的方式在等待服务器答复之前先停止导航。
我们需要CanDeactivate守卫。
步骤与canactivate一样,这里就不再赘述了直接上代码
1.unsave.guard.ts
2.路径配置
当离开home时浏览器会弹出消息框 如果确认就会路由到其他组件,如果取消就会留在当前
3.resolve守卫
预先获取组件数据,导航前预先加载路由信息
1.在guard文件夹里添加文件product.resolve.ts
2.product.component.ts里实例化
3.路径配置
4.providers里注入
5.product.component.html
最近跳入了angular4的坑,之前看的angular权威教程是angularJS1.的版本,之后的angular2和angular4改动非常大,可以说是两个框架了(雷锋和雷峰塔),google公司只对angularJS1.维护两年,所以果断弃了angularJS,现在大多是angular2和angular4应用居多 锤子科技官网http://www.smartisan.com/#/shop就是用angular4写的,现在学到了路由,跟着视频过了一遍,然后又自己写一遍代码加深记忆,视频是慕课网出的angular4.0从入门到实战 打造股票管理网站 有需要的小伙伴可以留言 路由这一章课程有三个小例子,spa (single page application)单页面应用,路由真的炒鸡有用啊感觉, 才接触angular我想记录下来因为忘的炒鸡快啊衰,环境搭建的时候有各种错误 搞得心累 要装node,angularCli npm 环境搭建这里有问题也可以留言因为我真的碰到好多问题!!!! 我用的是webstorm2017.2 这个博文内容比较杂,有时间分开一下 这样不好找,内容大概有
子路由
路由传参三种方式
路由守卫
第一个超简单路由应用
说明:点击主页显示的是home组件的内容,商品详情是product组件的内容,我会放截图还有需要注意的地方
先说一下流程(环境搭建就不说了,网上有很多教程博文)
1.创建项目 ng new myrouter –routing
/———后面的–routing必须加上,才会生成路由配置文件,我下面那个图里可以看到app-routing-modules.ts———/
2.npm install jquery –save (两个横线!)
npm install bootstrap –save
npm install @types/jquery –save-dev
npm install @types/bootstrap –save-dev
(后面这两个也要装上,因为angular是typescript写的,而这两个库
javascript~~大概是因为这个)
3.接下来就是添加你要用的组件了
ng g component home
ng g component product
ng g component code404
4.准备工作都做好了,现在开始码代码~
app.component.html
标签必须有,这相当于插座,让待显示的组件的内容知道放到哪里," title="">
home.component.html
<div class="home"> <p> 这里是主页组件 </p> </div>
product.component.html
<div class="product"> <p> 这里是商品信息组件 </p> <p> 商品ID是 </p> <p> 商品ID是 </p> </div>
组件里的内容可以自由构思,接下来就是路由配置了
在app-routing.modules.ts里配置,只需要修改Routes里内容即可,
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'; const routes: Routes = [ {path: 'home', component: HomeComponent}, {path: 'product', component: ProductComponent}, {path: '', redirectTo: '/home', pathMatch: 'full'}, {path: '**', component: Code404Component} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
{path: '', redirectTo: '/home', pathMatch: 'full'},
这个意思就是一进入页面就跳转显示指定的home组件的内容,这个可以自己指定,path不能以斜杠(/)开头。 路由器会为解析和构建最终的URL,这样当我们在应用的多个视图之间导航时,可以任意使用相对路径和绝对路径。路由的定义顺序是刻意如此设计的。路由器使用先匹配者优先的策略来匹配路由,所以,具体路由应该放在通用路由的前面。在上面的配置中,带静态路径的路由被放在了前面,后面是空路径路由,因此它会作为默认路由。而通配符路由被放在最后面,这是因为它能匹配上每一个URL,因此应该只有在前面找不到其它能匹配的路由时才匹配它。
{path: 'product', component: ProductComponent}, {path: '**', component: Code404Component}
这两行代码,第一行是常规指定路径的方法,一般在输入ProductComponent时会自动在文件前面添加import{…},alt+enter就可以添加 我下载的webstorm没有自己配置,如果设置快捷键了就按自己的,,第二行path路径是通配符,意思就是如果用户输入的路径不存在就会显示指定的组件Code404Component
import {HomeComponent} from './home/home.component'; import {ProductComponent} from './product/product.component'; import {Code404Component} from './code404/code404.component';
子路由、和三种给路由传递参数的方法
要求:在商品信息组件设置点击“显示商品描述”,首先添加一个 product-desc组件,编辑对应的html文件,想让这个组件在product组件下显示,所以正题来了。。。。
1. product.html
<div class="product"> <p> 这里是商品信息组件 </p> <a [routerLink]="['./desc',2]">点击查看商品详情</a> </div> <router-outlet></router-outlet>
标签必须写,routerLink是一个数组,后面的数字是传入的参数,子路由是./
2.配置路由,如果要传入参数记得格式path:’desc/:id’ id是自定义的
{path: 'product', component: ProductComponent, children: [ {path: 'desc/:id', component: ProductDescComponent} ]},
3.到这一步已经实现了子路由,对于传进去的参数可以获取到
因为是给子路由传递的参数,所以在product-desc.component.html
<p>这里是商品描述</p> <p> 商品ID是{{productId}}</p>
product-desc.component.ts
import { Component, OnInit } from '@angular/core'; import {ActivatedRoute} from '@angular/router'; @Component({ selector: 'app-product-desc', templateUrl: './product-desc.component.html', styleUrls: ['./product-desc.component.css'] }) export class ProductDescComponent implements OnInit { public productId: number; constructor(private routerInfo: ActivatedRoute) { } ngOnInit() { this.productId = this.routerInfo.snapshot.params['id']; } }
这样就可以在路由到product-desc时页面上就会显示productId
传递参数的方法有三种,一种是上面提到的在路径中传递,还有一种是在查询参数中传递 代码如下
product.component.html
<a [routerLink]= "['./desc']" [queryParams] = "{id:1}"> 点击查看商品详情</a>
配置路径这里:
{path: 'product', component: ProductComponent, children: [ {path: 'desc', component: ProductDescComponent} ]},
product-desc.component.html
ngOnInit() { this.productId = this.routerInfo.snapshot.queryParams['id']; }
第三种方式:在路由配置中添加静态数据传递参数
路由配置:
{path: 'product', component: ProductComponent, children: [ {path: 'desc', component: ProductDescComponent, data: [{'id': 1}]} ]},
获取 :data[0][‘id’]表示获取路由参数中第一个对象的id属性
this.productId = this.routerInfo.snapshot.data[0]['id'];
product.component.html
<a [routerLink]= "['./desc']"> 点击查看商品详情</a>
路由守卫
这一章剩下的内容就是路由守卫,看一下angular4中文社区对路由守卫的描述
上面的例子,用户都能在任何时候导航到任何地方。 但有时候这样是不对的。
该用户可能无权导航到目标组件。
可能用户得先登录(认证)。
在显示目标组件前,我们可能得先获取某些数据。
在离开组件前,我们可能要先保存修改。
我们可能要询问用户:你是否要放弃本次更改,而不用保存它们?
我们可以往路由配置中添加守卫,来处理这些场景。守卫返回一个值,以控制路由器的行为:
如果它返回true,导航过程会继续
如果它返回false,导航过程会终止,且用户会留在原地。
守卫还可以告诉路由器导航到别处,这样也取消当前的导航。
守卫可以用同步的方式返回一个布尔值。但在很多情况下,守卫无法用同步的方式给出答案。 守卫可能会向用户问一个问题、把更改保存到服务器,或者获取新数据,而这些都是异步操作。
因此,路由的守卫可以返回一个Observable或Promise,并且路由器会等待这个可观察对象被解析为true或false。
路由器支持多种守卫:
用CanActivate来处理导航到某路由的情况。
用CanActivateChild处理导航到子路由的情况
用CanDeactivate来处理从当前路由离开的情况。
用Resolve在路由激活之前获取路由数据。
用CanLoad来处理异步导航到某特性模块的情况。
在分层路由的每个级别上,我们都可以设置多个守卫。 路由器会先按照从最深的子路由由下往上检查的顺序来检查CanDeactivate()和CanActivateChild()守卫。 然后它会按照从上到下的顺序检查CanActivate()和CanActivateChild()守卫。 如果特性模块是异步加载的,在加载它之前还会检查CanLoad()守卫。 如果任何一个守卫返回false,其它尚未完成的守卫会被取消,这样整个导航就被取消了。
这一章介绍三个路由守卫
1.canactivate:要求认证
应用程序通常会根据访问者来决定是否授予某个特性区的访问权。 我们可以只对已认证过的用户或具有特定角色的用户授予访问权,还可以阻止或限制用户访问权,直到用户账户激活为止。
CanActivate守卫是一个管理这些导航类业务规则的工具。
CanActivate:[] 接收一个数组,可以指定多个路由守卫,当视图进入此路由时,所有守卫会被依次调用,如果有一个守卫返回false,则路由请求会被拒绝掉,看一下步骤
a.创建一个directive文件夹名为guard
b.在此文件夹下建一个typescript文件,命名为login.guard.ts
c.编写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; } }
d.配置路由,可以添加多个守卫
{path: 'home', component: HomeComponent, canActivate: [LoginGuard]},
e.路由配置文件里要添加providers
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [LoginGuard] })
我测试了一下,对一个组件添加多个守卫,给上一个home组件按照同样的步骤添加一个test.ts ,让这个守卫返回false,果然home这个组件就没法加载出来
test.ts
import {CanActivate} from '@angular/router'; export class TestGuard implements CanActivate { canActivate () { return false; } }
2.来说下CanDeactivate 处理未保存的更改
在现实世界中,我们得先把用户的改动积累起来。 我们可能不得不进行跨字段的校验,可能要找服务器进行校验,可能得把这些改动保存成一种待定状态,直到用户或者把这些改动作为一组进行确认或撤销所有改动。
当用户要导航到外面时,该怎么处理这些既没有审核通过又没有保存过的改动呢? 我们不能马上离开,不在乎丢失这些改动的风险,那显然是一种糟糕的用户体验。
我们应该暂停,并让用户决定该怎么做。如果用户选择了取消,我们就留下来,并允许更多改动。如果用户选择了确认,那就进行保存。
在保存成功之前,我们还可以继续推迟导航。如果我们让用户立即移到下一个界面,而保存却失败了(可能因为数据不符合有效性规则),我们就会丢失该错误的上下文环境。
在等待服务器的答复时,我们没法阻塞它 —— 这在浏览器中是不可能的。 我们只能用异步的方式在等待服务器答复之前先停止导航。
我们需要CanDeactivate守卫。
步骤与canactivate一样,这里就不再赘述了直接上代码
1.unsave.guard.ts
import {CanDeactivate} from '@angular/router'; import {HomeComponent} from "../home/home.component"; export class UnsaveGuard implements CanDeactivate <HomeComponent> { canDeactivate (component: HomeComponent) { return window.confirm('你还没有保存,确定离开吗?'); }
2.路径配置
{path: 'home', component: HomeComponent, canActivate: [LoginGuard, TestGuard], canDeactivate: [UnsaveGuard]}, @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [LoginGuard, TestGuard, UnsaveGuard], })
当离开home时浏览器会弹出消息框 如果确认就会路由到其他组件,如果取消就会留在当前
3.resolve守卫
预先获取组件数据,导航前预先加载路由信息
1.在guard文件夹里添加文件product.resolve.ts
import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router'; import {Injectable} from '@angular/core'; import {Product} from '../product/product.component'; @Injectable () export class ProductResolve implements Resolve <Product> { constructor(private router: Router) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { const productId: number = route.params['id']; if (productId == 1) { return new Product(2); }else { this.router.navigate(['/home']); return undefined; } } }
2.product.component.ts里实例化
export class Product { constructor(public productIds: number) { } }
3.路径配置
{path: 'product/:id', component: ProductComponent, children: [ {path: 'desc', data: [{id: 1}], component: ProductDescComponent} ], resolve: [ProductResolve]},
4.providers里注入
providers: [LoginGuard, TestGuard, UnsaveGuard, ProductResolve],
5.product.component.html
<div class="product"> <p> 这里是商品信息组件 </p> <a [routerLink]= "['./desc']"> 点击查看商品详情</a> {{productIds}} </div> <router-outlet></router-outlet> 这篇博文到这里就完了,内容大概就这么多,也不是很全面,可以去中文社区看看,还有对应的例子可以练手,一边敲一边回忆,发现自己忘光了,然后又查文档看视频,总算是写完了,过一遍果然是有效果的哈哈哈哈哈~~~~~ 脑袋有点糊,如果哪里不正确还希望能指正,
相关文章推荐
- Angular 4.0从入门到实战 打造属于你自己的股票管理网站
- Angular 4.0从入门到实战 打造管理网站 - 慕课网
- docker入门实战(理论+实践)系列---进入docker的三种方式
- 网站后端_Python+Flask.0004.FLASK配置管理之三种方式加载外部配置?
- Angular 4 学习笔记 从入门到实战 打造在线竞拍网站 基础知识 快速入门 个人感悟
- Linux学习之CentOS(二)----centos连接网络的三种方式及 远程登录管理工具SecureCRT的使用
- Asp.NET+Oracle? 逐浪CMS致力打造功能强大的新一代网站内核管理系统
- Struts2三种传参方式(从jsp页面传到Action)
- Spring 入门学习(二)之 三种实例方式
- C# 给多线程传参的三种方式
- (实战)使用ExtJs+WCF打造分行信息管理功能的一些心得
- TensorFlow 中文资源精选,官方网站,安装教程,入门教程,实战项目,学习路径。
- Asp.NET+Oracle? 逐浪CMS致力打造功能强大的新一代网站内核管理系统
- Spring入门之实例化Bean的三种方式
- JSP传参的九种方式(主要用前三种)
- yii2实战教程之新手入门指南-简单博客管理系统
- 新手学DIV+CSS商业网站布局从入门到精通(实战案例版) 朱印宏 pdf扫描版
- 大流量网站的三种Mysql数据库扩展方式
- servlet(三)-如何使用传参-三种转发方式、传递参数以及对象中数据的范围
- Tomcat实现session保持的三种方式、使用msm方式搭建jsp网站