路由策略
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'}
]
})
跳转方式
1 指令跳转
<div [routerLink]="['/set']" >jump to setting</div>
注意引号的写法
routerLink做了两件事情,
- 第一是调用 this.router.navigateByUrl(this.urlTree);return false;//跳转并渲染
- 第二是preventDefault(),
示例
<nav routerLinkActive="activeClass">
<button [routerLink]="['/set']" >set</button>
<button [routerLink]="['/main']" >main</button>
</nav>
routerLinkActive:当被(激活)点击或者子元素被(激活)点击时,调用css的类进行样式展示
2 代码跳转
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