在路由开始之前,先补一下Angular的一些基础知识:
概念:
- 组件:是Angular应用的基础构建块,可以理解为是一段带有逻辑和数据的html
- 模块:用来将应用中不同的部分组织成一个Angular框架,可理解的单元
- 指令:允许向html元素中添加自定义行为
- 服务:用来封装可重用的业务逻辑
框架认识:
Angular Route导航
用到路由时,最常用的对象有:
- Routes:路由配置,保存哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示组件
- RouterOutlet:在HTML中标记路由内容呈现位置的占位符指令
- Router:负责在运行时执行路由的对象,可通过调用期navigate()和navigateByUrl()方法来导航到一个指定的路由
- Routerlink:在HTML中声明路由导航用到的指令
- ActivatedRoute:当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等
一:定义路由 |
{ path: '',component:HomeComponent },{ path:'product',component:ProductComponent }
定义根路由:RouterModule.forRoot(routes)
二:路由导航类型 |
使用命令导航[routerLink]:
如导航到home主页<a [routerLink]="['/product']">商品页面</a>
使用代码导航:
1.先在构造函数中添加Router:
constructor(private router:Router){}
2.在指定方法中添加导航代码:
this.router.navigate(['/product']);
三:在html中定位插座的位置 |
<router-outlet></router-outlet >
以上步骤以能成功导航
四:通用路由 |
为了防止程序崩溃,所以设置一个通用路由,即当输入不存的URL时,导航到指定页面
{ path:'*',component:Code404Component }
因为路由具有先匹配者优先的原则,所以配置路由时通用路由应该放在所有路由的后面
五:在路由中传递数据 |
在URL中传递数据
1.路由配置
{ path:'product/:id',component:ProductComponent }
2.在跳转路由入口时传递实际的数值
[routerLink]="['/product',1]"
或
this.router.navigate(['/product',1])
在查询参数中传递数据
1.[routerLink]="['/product']" [queryParams]="{id:1}"
2.接收数据
先在构造函数中声明ActivatedRoute对象
constructor(private routeInfo:ActivatedRoute) { }
然后在ngOnInit()接收参数
ngOnInit() {
//参数快照方式
this.productId = this.routeInfo.snapshot.queryParams["id"];
//参数订阅方式,写在匿名函数中
this.routeInfo.params.subscribe((params:Params) => this.productId=params["id"]);
}
使用参数订阅方式,是因为当有多个方式跳转到同一路由时,但是传递的参数不同,但是ngOnInit()只有在第一次创建对象时才执行,由于我们接收参数时又是写在ngOnInit()里面的,所以如果使用参数快照的方式,只有第一次导航路由时参数被传进来了,以后再导航该路由时,参数都传不进来了,因为不执行ngOnInit()方法了
六:重定向路由 |
使用情况:
在用户访问一个特定的地址时,将其重定向到另一个指定的地址
如:
www.aaa.com => www.aaa.com/product
ww.aaa.com/x => www.aaa.com/y
比如:在设置路由时,默认空路径,导航到HomeComponent,但是这样不符合规范,路径名最好是组件名,
{ path: 'home',component:HomeComponent }
然后可以用路由重定向,当到默认路径下时,重导向到home路径下
{ // 路由重定向 path:'',redirectTo:'/home',pathMatch:'full' }
七:子路由 |
1.想给谁添加子路由就在谁的路由配置下添加children
如:
path:'product',component:ProductComponent,// 定义子路由
children:[
{
path:'',component:ProductDescComponent
}
]
2.在父路由的html中添加一个子路由的插座
八:主路由和辅助路由 |
1.配置辅助路由出口:一个页面只能有一个路由插座,这是还想一块显示隐藏多个组件,这时就可以定义一个辅助路由
<router-outlet></router-outlet >
<router-outlet name="aux"></router-outlet>
2.然后配置路由
{ path:'chat',component:ChatComponent,outlet:'aux' }
3.最后定义辅助路由入口
[routerLink]="[{outlets:{primary:'home',aux:'chat'}}]"
要表明是谁的辅助路由,即主路由:primary
九: 路由守卫 |
- CanActivate:处理导航到某路由的情况
- CanDeactivate:处理从当前路由离开的情况
- Resolve:在路由激活之前获取路由数据
CanActivate:在满足一定条件下才能进入下一个路由
1.首先定义守卫,实现CanActivate接口
export class LoginGuard implements CanActivate{
canActivate(){
let loggedIn:boolean = Math.random() < 0.5;
if(!loggedIn){
console.log("用户未登录");
}
return loggedIn;
}
}
2.然后在要跳转到的路由配置中,添加canActivate:[LoginGuard]
CanDeactivate<返回到的路由组件> :处理从当前路由离开的情况
1.首先定义守卫,实现CanDeactivate<>接口
export class UnsavedGuard implements CanDeactivate<ProductComponent>{
canDeactivate(component: ProductComponent){
return window.confirm("你还没有保存,确定要离开吗?");
}
}
2.然后在要跳转到的路由配置中,添加canDeactivate:[UnsavedGuard]
Resolve<返回的东西>:在路由激活之前获取路由数据
1.定义守卫
@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"];
if(productId == 1){
return new Product(1,"iPhone7");//返回Product对象
} else {
this.router.navigate(['/home']);
return undefined;
}
}
注意项: 导入@Injectable()装饰器 构造函数中定义Router对象 返回的是Product对象,所以要在要跳转到的路由的组件中定义Product类
export class Product {
constructor(public id:number,public name:string){}
}
2.然后在要跳转到的路由配置中,添加 resolve:{ product:ProductResolve}
3.最后在要激活的路由控制器中接收数据
export class ProductComponent implements OnInit {
private productId:number;
private productName:string;
constructor(private routeInfo:ActivatedRoute) { }
ngOnInit() {
//订阅传进来的数据
this.routeInfo.data.subscribe((data:{product:Product}) =>{
this.productId = data.product.id;
this.productName = data.product.name;
});
}
}
设置Resolve路由的原因:防止在有插值绑定的html中,在数据没常见来时页面已加载的情况
例子 |
下面是有关路由知识的例子:
链接: https://pan.baidu.com/s/1nvj7gmd 密码:rsak
总结 |
完成一个路由跳转的步骤:
- 定义路由插座
- 配置路由
- 定义路由入口