路由

主要是5大类

 

名称 说明

Routes 

路由配置,保存哪个URL对应展示哪个组件,以及在哪个RouuterOutlet中展示组件

RouterOutlet

在html中标记路由内容呈现位置的占位符指令 

Router  

负责在运行时执行路由的对象,可以通过调用器navigate()和navigateByUrl()方法来导航到一个指定的路由

RouterLink

在html中声明路由导航用的指令 

ActivatedRoute

当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等

 

一、Routes

 

const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' }, //重定向,将空的路径重定向到home组件
{ path: 'home', component: HomeComponent },
{ path: 'product-detail/:id', component: ProductDetailComponent },
{ path: '**', component: NotFoundComponent}//通用路由,放在最后面,因为ng是先匹配优先策越
]; 

 


注意:path中不能配置 / 线 如 path:'/' 不允许

 

二、Router 、ActivatedRoute

通过构造函数的依赖注入来获取这个Router、ActivatedRoute

constractor(private router:Router, private activatedRoute:ActivatedRoute){}

 

Router使用:

this._router.navigate(['/home']);
//或传参数
this._router.navigate(['/product-detail', 2]);

 

三、路由传递数据


主要有3种:

1.在查询参数中传递数据

product?id=1&name=2

获取:

//通过参数快照 
this._activeRoute.snapshot.queryParams['id']; 
//或是参数订阅
this._activeRoute.queryParams.subscribe((params:Params)=>this.id = params['id'])

 

2.在路由路径中

product/:id

 

获取:

//通过参数快照 
this._activeRoute.snapshot.params['id'];
//或是参数订阅
this._activeRoute.params.subscribe((params:Params)=>this.id = params['id'])

 

3.在路由配置中

{path:'', component:HomeCompoent, data:[{isHome:true}]}

 

获取:

this._activeRoute.snapshot.data[0]['id']  
//或是参数订阅
this._activeRoute.data.subscribe((data: Data) => { this._productId = data[0]['id']; });

 

参数快照和参数订阅,当自身路由到自身的时候,如果路由数据有变化使用参数订阅

 

 四、子路由

  在路由配置中使用children属性,在父组件中添加路由输出outlet,如下,在HomeComponent的模板中添加<router-outlet>用来表示子路由及DetailComponent显示的位置


const routes: Routes = [
{ path: 'home', component: HomeComponent,children:[
    { path: 'detail/:id', component: DetailComponent}
] },

]; 
//home.component.html

<p>
  这是home组件
</p>
<!--使用相对路径来跳转子路由-->
<a [routerLink]="['./detail', 2]"></a> <router-outlet></router-outlet>

  注意:使用相对路径来跳转子路由,相对于当前html

五、辅助路由

  一个组件只能有一个主路由输出,但是可以有多个辅助路由输出,添加name属性的为辅助路由输出

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

      配置:

1 const routes: Routes = [
2 { path: '', redirectTo: '/home', pathMatch: 'full' }, 
3 { path: 'home', component: HomeComponent},
4 //使用outlet属性指明该组件由哪个路由输出
5 { path: 'product-detail/:id', component: ProductDetailComponent,outlet:'aux' },
6 { path: '**', component: NotFoundComponent}
7 ]; 

      使用:

//primary是指定主路由显示哪个组件,可选。意思是辅助路由在显示商品详情的时候,主路由显示主页
<a [routerLink]="[{outlets: {primary:'home', aux: 'product-detail/2'}}']"></a>
//辅助路由不显示
<a [routerLink]="[{outlets: {primary:'home', aux: null]"></a>

 

六、路由守卫

    路由守卫分为3种

名称 说明
canActivate 路由进入某组件时的判断,如点击进入某路由时,如发现不满足某些条件,则不允许进入该路由
canDeactivate 离开路由时,如不满足某条件不允许离开。如提示用户没有保存信息,不允许离开的提示
resolve 进入某路由前,将一些数据提前加载,如http请求数据,可放在这里面,数据请求到了再跳转

 

 1、canActivate

 新建login.activate.ts文件

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

export class LoginActivate implements CanActivate {
  canActivate() {
    const loggedIn = Math.random() < 0.5;
    return loggedIn;
  }
}

   配置路由

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' },
//配置守卫
  { path: 'home', component: HomeComponent, canActivate: [LoginActivate] },
  { path: 'product-detail/:id', component: ProductDetailComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { enableTracing: false })
  ],
    //将守卫注册
  providers: [LoginActivate],
  exports: [RouterModule]
})

 

   2、canDeactivate

   新建leave.deactivate.ts文件

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

export class LeaveDeactivate implements CanDeactivate<ProductDetailComponent> {
  canDeactivate(product: ProductDetailComponent) {
    const loggedIn = Math.random() < 0.5;
    return window.confirm('您还有信息未保存,请保存再离开?');
  }
}

路由配置

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' },
  { path: 'home', component: HomeComponent, canDeactivate: [LeaveDeactivate] },
  { path: 'product-detail/:id', component: ProductDetailComponent }
];

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

 

3、resolve

新建product.resolve.ts文件

import { Resolve } from '@angular/router';
import { Product } from './product.interface';
  import { Injectable } from '@angular/core';

  @Injectable()
export class ProductResolve implements Resolve<Product> {
  resolve() {
    const _porduct: Product = {
      id: 1,
      name: '',
      image: '',
      bigImage: '',
      description: '这个是第一个商品',
      price: '9.99',
      score: 5
    };
    return _porduct;
  }
}

 

配置:

 

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' },
  { path: 'home', component: HomeComponent, resolve: { product: ProductResolve } },
  { path: 'product-detail/:id', component: ProductDetailComponent }
];

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

 

使用:


import { ActivatedRoute, Data } from '@angular/router';
 
constructor(private _activeRoute: ActivatedRoute) { } ngOnInit() {
this._activeRoute.data.subscribe((data: Data) => { this.currProduct = data['product']; }); }

 

 

 

七、路由懒加载

如果在app.module.ts里面注册的模块都会被打包成一个js文件,在html打开时该文件就会被加载,一个大文件浏览器加载可能很慢,所以有了延迟加载,在使用该模块的时候才会加载这个js文件(会生成单独的文件)

使用loadChildern来延迟加载模块,值为字符串,包括该模块的位置+文件名+模块名,默认路径在src,因此需要添加app路径

 

 

const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' }, 
{ path: 'home', component: HomeComponent },
{ path: 'product-detail/:id', component: ProductDetailComponent },
//延迟加载about模块
{ path: 'about', loadChildren: 'app/about/about.module#AboutModule' },
{ path: '**', component: NotFoundComponent}

使用build之后会多生成一个js文件,如下

 

 

 

在延迟加载模块中,需要新建一个路由模块,或是添加进aboutModule中也可以,用来导航到延迟加载模块的组件中

 

posted @ 2018-07-26 11:46  洛歌  阅读(164)  评论(0编辑  收藏  举报