您的位置:首页 > Web前端 > AngularJS

angular路由&导航

2018-03-12 17:23 274 查看

一、路由

概述大多数带路由的应用都要在index.html的标签下先添加一个元素,来告诉路由器该如何合成导航用的URL。
配置路由
//导入模块
import { RouterModule, Routes } from '@angular/router';
配置路由表
const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent },
{ path: 'hero/:id',      component: HeroDetailComponent },
{
path: 'heroes',
component: HeroListComponent,
data: { title: 'Heroes List' }
},
{ path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];

@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
)
// other imports here
],
...
})
export class AppModule { }
每个定义都被翻译成了一个Route对象。该对象有一个path字段,表示该路由中的URL路径部分,和一个component字段,表示与该路由相关联的组件。重定向路由需要一个pathMatch属性,来告诉路由器如何用URL去匹配路由的路径,否则路由器就会报错。 在本应用中,路由器应该只有在完整的URL等于''时才选择HeroListComponent组件,因此我们要把pathMatch设置为'full'。从技术角度说,pathMatch = 'full'导致URL中剩下的、未匹配的部分必须等于''。 在这个例子中,跳转路由在一个顶级路由中,因此剩下的URL和完整的URL是一样的。pathMatch的另一个可能的值是'prefix',它会告诉路由器:当剩下的URL以这个跳转路由中的prefix值开头时,就会匹配上这个跳转路由。在这里不能这么做!如果pathMatch的值是'prefix',那么每个URL都会匹配上''。尝试把它设置为'prefix',然后点击Go to sidekicks按钮。别忘了,它是一个无效URL,本应显示“Page not found”页。 但是,我们看到了“英雄列表”页。在地址栏中输入一个无效的URL,我们又被路由到了/heroes。 每一个URL,无论有效与否,都会匹配上这个路由定义。默认路由应该只有在整个URL等于''时才重定向到 HeroListComponent,别忘了把重定向路由设置为pathMatch = 'full'。
// 使用路由=====================

template: `
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
//传递参数的情况
<a [routerLink]="['/index','我是默认值']" routerLinkActive="active" >首页</a>
<!--<a routerLink='/index/我是默认值'routerLinkActive="active" >首页</a>-->
</nav>
<router-outlet></router-outlet>
`
每个a标签上的RouterLinkActive指令可以帮用户在外观上区分出当前选中的“活动”路由。 当与它关联的RouterLink被激活时,路由器会把CSS类active添加到这个元素上。当需要传递参数时
<a [routerLink]="['/detail',hero.id]">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</a>

多级路由新建一个模块文件夹(比如商品,包含列表、详情、评论等组件)。将各组件移入该文件夹
模仿app.module.ts新建一个module(如goods.module.ts),并在app.module.ts中注册、imports路由配置的顺序很重要。 路由器会接受第一个匹配上导航所要求的路径的那个路由。 所以我们应该把AppRoutingModule放在最下面
//app.module.ts
imports: [
BrowserModule,
FormsModule,
HttpModule,
GoodsModule, //这个是新建的子模块
AppRoutingModule
],

新建子模块的路由
import { RouterModule, Routes } from '@angular/router';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { HeroesComponent } from './heroes.component';
const routes: Routes = [

{
path: 'heroes',
component: HeroesComponent
},
{
path: 'detail/:id',
component: HeroDetailComponent
},
];

@NgModule({
imports: [ RouterModule.forChild(routes) ],
exports: [ RouterModule ]
})
export class HeroesRoutingModule {}

注意:RouterModule.forChild(routes) 4. 去掉AppRoutingModule重复的部分
路由跳转
//导入路由类
import {Router} from '@angular/router';
constructor(
private hs:HeroService,
private router: Router,
) { }

onSelect(hero){
this.router.navigate(['/detail', hero.id]);
}

获取路由信息
import { Component, OnInit,Input } from '@angular/core';

//导入服务
import {HeroService} from '../../services/hero.service';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Location }                 from '@angular/common';

import 'rxjs/add/operator/switchMap';
import {Hero} from '../../models/hero';
@Component({
selector: 'app-hero-detail',
templateUrl: 'hero-detail.component.html',
styleUrls: ['hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
_hero:Hero;

id:string;
constructor(
private hs:HeroService,
private route: ActivatedRoute,
private location: Location
) { }

ngOnInit() {
//使用快照方式获取数据
/* let id=this.route.snapshot.paramMap.get('id');
this.hs.getHero(id)
.then((hero: Hero) => this.hero = hero);*/

this.route.paramMap
.switchMap((params: ParamMap) => this.hs.getHero(+params.get('id')))
.subscribe(hero => this._hero = hero);
}

//可以这么写
/*this.route.paramMap
.switchMap((params: ParamMap) => {
console.log(params.get('id'));
return this.hs.getHero(+params.get('id'));
})
.subscribe(hero => this._hero = hero);*/

goBack(){
this.location.back();
}

}

二、子路由

构建子路由步骤构建子路由中的组件
PersonalCenterComponent,
MyMenusComponent,
MyCollectionsComponent,
SettingComponent
其中PersonalCenterComponent为子路由导航组件,内部含有新的<router-outlet></router-outlet>
<h1>个人中心</h1>
<div>
<div class="col-lg-12 col-md-12">
<a routerLink="./setting">setting</a>
<a routerLink="./menus">menus</a>
<a routerLink="./collections">collections</a>
</div>
</div>
<router-outlet></router-outlet>
** 注意 routerLink='./' **
构建子路由模块,并导入上一步构建的组件
import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';
import { FormsModule }    from '@angular/forms';
import {PersonalCenterComponent} from './personal-center.component';
import {MyMenusComponent} from './my-menus/my-menus.component';
import {SettingComponent} from './setting/setting.component';
import {MyCollectionsComponent} from './my-collections/my-collections.component';
import {PersonalRoutingModule} from './personal-routing.module';
@NgModule({
imports: [
CommonModule,
FormsModule,
PersonalRoutingModule
],
declarations: [
PersonalCenterComponent,
MyMenusComponent,
MyCollectionsComponent,
SettingComponent
],
providers: [  ]
})
export class PersonalModule {}

构建子模块的路由(注意 imports: [RouterModule.forChild(routes)])
import {NgModule}             from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {PersonalCenterComponent} from './personal-center.component';
import {MyMenusComponent} from './my-menus/my-menus.component';
import {SettingComponent} from './setting/setting.component';
import {MyCollectionsComponent} from './my-collections/my-collections.component';

const routes: Routes = [
{
path: 'personal-center',
component: PersonalCenterComponent,
children: [
{
path: 'setting',
component: SettingComponent,
},
{
path: 'menus',
component: MyMenusComponent,
},
{
path: 'collections',
component: MyCollectionsComponent,
},
{
path: '',
component: MyMenusComponent,
}
]
}];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class PersonalRoutingModule {
}

把子模块导入到app.module.ts注意放置的顺序,要放在根路由的上面
imports: [
BrowserModule,
FormsModule,
HttpModule,
HeroesModule,       //二级路由
PersonalModule,     //个人中心模块
AppRoutingModule   //根路由

], ```

三、路由守卫

可以往路由配置中添加守卫,守卫返回一个值,以控制路由器的行为:如果它返回true,导航过程会继续
如果它返回false,导航过程会终止,且用户会留在原地。
守卫对象:用CanActivate来处理导航到某路由的情况。
用CanActivateChild来处理导航到某子路由的情况。
用CanDeactivate来处理从当前路由离开的情况.
用Resolve在路由激活之前获取路由数据。
用CanLoad来处理异步导航到某特性模块的情况。
CanActivate应用程序通常会根据访问者来决定是否授予某个特性区的访问权。 我们可以只对已认证过的用户或具有特定角色的用户授予访问权,还可以阻止或限制用户访问权,直到用户账户激活为止。CanActivate守卫是一个管理这些导航类业务规则的工具。使用守护路由的步骤创建
import { Injectable }     from '@angular/core';
import { CanActivate }    from '@angular/router';

@Injectable()
export class AuthGuard implements CanActivate {
canActivate() {
console.log('AuthGuard#canActivate called');
return false;
}
}
注意它是一个service
子子模块中注册
providers: [AuthGuard]

在子路由的路由表中使用
//路由守护
import { AuthGuard }                from '../services/auth-guard.service'
const routes: Routes = [
{
path: 'personal-center',
component: PersonalCenterComponent,
canActivate: [AuthGuard],  //注意这里****
children: [
{
path: 'setting',
component: SettingComponent,

},
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息