路由策略
http://host[:port]/[/path][?query][#hash] [/path] PathlocationStrategy [#hash] HashlocationStrategy
比如
PathlocationStrategy http://localhost:4200/list HashlocationStrategy http://localhost:4200/#/list
HashlocationStrategy
浏览器发送请求不会带上hash的部分,因此服务器只需要返回应用首页,angular会在获取首页后根据hash的内容找对应的路由组件
开启方法
@NgModule( imports:[ RouterModule.forRoot(rootRouterConfig,{useHash:true}) ] )
PathlocationStrategy
服务器可以根据请求参数进行单独处理
使用的前提条件
- 浏览器必须支持H5的history.pushState()方法,这个方法令RouterLink指令在跳转时即使修改了URL的path部分,却依然不会引起界面刷新
- 服务器需要进行重定向(单一入口),避免404访问错误
- 需要设置base路径,因为是以base路径为前缀来生成和解析URL的
base路径设置方法
1通常形式
<!-- index.html --> <head> <base href="/app"> </head>
2 优先级最高
import {APP_BASE_HREF} from '@angular@common'; @NgModule({ providers:[ {provide:APP_BASE_HREF,useValue:'/app'} ] })
<div [routerLink]="['/set']" >jump to setting</div>
注意引号的写法
routerLink做了两件事情,
示例
<nav routerLinkActive="activeClass"> <button [routerLink]="['/set']" >set</button> <button [routerLink]="['/main']" >main</button> </nav>
routerLinkActive:当被(激活)点击或者子元素被(激活)点击时,调用css的类进行样式展示
import {Router} from '@angular/router'; export class listComponent { constructor(private _router:Router) { _router.navigateByUrl('/collection'); _router.navigate('/collection'); _router.navigateByUrl(['/collection',{name:'title'}]);//传参数 } }
路由参数
// app.routes.ts export const AppRouters:RouterConfig=[ {path:'detail/:id',component:DetailComponent} ];
使用
<a [routerLink]="['/detail',1]" > <a [routerLink]="'/detail/1'" > _router.navigate(['/detail',1]) _router.navigate('/detail/1')
Query 参数
http://localhost:3000/list?limit=5 //查看列表的前五个 写法 <a [routerLink]="['list']" [queryParams]="{limit:5}" > this._router.navigate(['/list'],{ queryParams:{limit:5} }); this._router.navigateByUrl('/list?limit=5');
import { Component,OnInit,OnDestroy } from '@angular/core'; import {ActivatedRoute} from '@angular/router'; @Component({ selector: 'app-persons',templateUrl: './persons.component.html',styleUrls: ['./persons.component.css'] }) export class PersonsComponent implements OnInit,OnDestroy { contacts:any[]; private limit:number; private sub:any; constructor(private _activatedRoute:ActivatedRoute) { } ngOnInit() { this.getContacts(); } getContacts() { this.sub=this._activatedRoute.queryParams.subscribe(params=>{ this.limit = parseInt(params['limit']); if(this.limit) { this.contacts.splice(this.limit); } }) } ngOnDestroy(){ this.sub.unsubscribe(); } }
子路由
// admin.routes.ts 这是AdminModule的路由 { path:'main',component:MainComponent,children:[ {path:'',redirectTo:'detail',pathMatch:'full'},{path:'detail',component:DetailComponent},{path:'set',component:SetComponent} ] } //main.component.html,注意又加了一个router-outlet <p> admin - main works! </p> <a [routerLink]="'detail'">detail</a> <a [routerLink]="'set'">set</a> <router-outlet></router-outlet>
这样实现了界面上二级路由的效果
routes的拦截器
- 激活拦截 CanActivate 能否进入路由
- 激活拦截 CanActivateChild 控制是否允许激活子路由配置项
- 反激活拦截 CanDeactivate 能否离开当前路由
- 数据预加载拦截 Resolve
- 模块加载拦截 CanLoad
1激活拦截的应用情景,比如没有登陆无法看到首页
首先生成一个service: ng g s login
示意代码
import { Injectable } from '@angular/core'; import {CanActivate} from '@angular/router'; @Injectable() export class LoginService implements CanActivate { constructor() { } canActivate(){ return false;//禁止访问,返回false,允许访问返回true; } }
angular-cli生成服务时不会自动添加,因此需要手动写到*.moduel.ts
@NgModule({ ... providers:[LoginService] })
反激活拦截 CanDeactivate 能否离开当前路由
写法类似,不过实现的方法多一个参数
import { Injectable } from '@angular/core'; import {CanDeactivate,ActivatedRouteSnapshot,RouterStateSnapshot} from '@angular/router'; @Injectable() export class DeactivateService implements CanDeactivate<any>{ constructor() { } canDeactivate(component:any,route:ActivatedRouteSnapshot,state:RouterStateSnapshot){ //component.isModified() 意思是当前组件提供方法isModified()来判断能否离开 if(component.isModified()){ return true; }else{ return false; } } }
题外话注意点
我在 HomeModule 里面写 [(ngModel)] 的时候报错,是因为两点
1FormsModule 虽然导入到AppModule,但是没有导入HomeModule
2当在表单中使用[(ngModel)]时,必须要定义name属性
代码https://git.oschina.net/TimeIsGoOn/angular2-learn/tree/use-routes