学过Angular的人应该知道路由在这里的作用是帮你找到相应的界面,在Angular2中是帮你找到相应的组件。
总结:路由是导航的另一个名字。路由器就是从一个视图导航到另一个视图的机制
1、创建相应的模块组件
2、跳转方向说明
1)主页按钮点击英雄列表跳转heroes,点击仪表盘跳转dashboard
2)在heroes和dashboard界面中点击相应item跳转hero-detail
3、app目录下创建路由
1)修改index.html并在在<head>顶部区添加<base href="/">,后面说base href部分
<head> <base href="/">
2)创建路由文件app-routing.module.ts,并导入到app.module.ts中
app-routing.module.ts:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { DashboardComponent } from './dashboard.component'; import { HeroesComponent } from './heroes.component'; import { HeroDetailComponent } from './hero-detail.component';/**
* path: 路由器会用它来匹配浏览器地址栏中的地址
* component: 导航到此路由时,路由器需要创建的组件
**/
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent }, { path: 'detail/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroesComponent } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
app.module.ts://引入 @NgModule({ imports: [//导入相应模块 BrowserModule, FormsModule, AppRoutingModule//路由 ],
4、添加路由插座(Outlet)
把<router-outlet>标签添加到模板的底部。 RouterOutlet是RouterModule提供的指令之一。 当我们在应用中导航时,路由器就把激活的组件显示在<router-outlet>里面。
app.component.ts:
<nav>
<a routerLink="/dashboard" routerLinkActive="active">仪表盘</a>
<a routerLink="/heroes" routerLinkActive="active">英雄列表</a>
</nav>
<router-outlet></router-outlet>
注意,锚标签中的 [routerLink]绑定。 我们把 RouterLink指令( ROUTER_DIRECTIVES中的另一个指令)绑定到一个字符串。 它将告诉路由器,当用户点击这个链接时,应该导航到哪里。
5、参数化路由-跳转英雄详情
1)在app-routing.module.ts中添加英雄跳转
注意:路径中的冒号 (:) 表示 :id是一个占位符,当导航到这个 HeroDetailComponent组件时,它将被填入一个特定英雄的id。路由参数的值 总是字符串。{path: 'detail/:id',component: HeroDetailComponent}
2)添加返回方式
goBack(): void { this.location.back(); }
所需文件:
英雄实体类:
hero.ts
export class Hero {
id: number;
name: string;
}
heroes:
heroes.component.ts
import {Component, OnInit} from '@angular/core';
import {Router, ActivatedRoute} from '@angular/router';
import { Hero } from '../../entity/hero';
import { HeroService } from '../../service/hero.service';
@Component({
moduleId: module.id,
selector: 'my-heroes',
templateUrl:'heroes.component.html',
styleUrls: ['../../assets/css/heroes.component.css']
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(
private router: Router,
private route: ActivatedRoute,
private heroService: HeroService) { }
getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
ngOnInit(): void {
this.getHeroes();
}
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
gotoDetail(): void {
this.router.navigate(['/detail', this.selectedHero.id]);
}
add(name: string): void {
name = name.trim();
if (!name) { return; }
this.heroService.create(name)
.then(hero => {
this.heroes.push(hero);
this.selectedHero = null;
});
}
delete(hero: Hero): void {
this.heroService
.delete(hero.id)
.then(() => {
this.heroes = this.heroes.filter(h => h !== hero);
if (this.selectedHero === hero) { this.selectedHero = null; }
});
}
}
heroes.component.html
<h2>英雄列表</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
<button class="delete"
(click)="delete(hero); $event.stopPropagation()">x</button>
</li>
</ul>
<div *ngIf="selectedHero">
<h2>
{{selectedHero.name | uppercase}}是我的英雄
</h2>
<button (click)="gotoDetail()">查看详请</button>
</div>
heroes.component.css
.selected {
background-color: #CFD8DC !important;
color: white;
[class.selected]="hero === selectedHero"
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
button.delete {
float:right;
margin-top: 2px;
margin-right: .8em;
background-color: gray !important;
color:white;
}
dashboar:
dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { Hero } from '../../entity/hero';
import { HeroService } from '../../service/hero.service';
@Component({
moduleId: module.id,
selector: 'my-dashboard',
templateUrl: 'dashboard.component.html',
styleUrls: [ '../../assets/css/dashboard.component.css' ]
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
//添加了一个构造函数
constructor(private heroService: HeroService) { }
ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
}
dashboard.component.html
<h3>置顶英雄</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" routerLink="{{'../detail/'+hero.id}}"
routerLinkActive="active" class="col-1-4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</a>
</div>
dashboard.component.css
[class*='col-'] {
float: left;
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
a {
text-decoration: none;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
h4 {
position: relative;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
border-radius: 2px;
}
.module:hover {
background-color: #EEE;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}
hero-detail:
hero-detail.component.ts
// Keep the Input import for now, we'll remove it later:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import 'rxjs/add/operator/switchMap';
import { HeroService } from '../../service/hero.service';
import {Hero} from "../../entity/hero";
@Component({
moduleId: module.id,
selector: 'my-hero-detail',
templateUrl: 'hero-detail.component.html',
styleUrls: ['../../assets/css/hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
hero:Hero;
constructor(
private heroService: HeroService,
private route: ActivatedRoute,
private location: Location
) {}
ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.heroService.getHero(+params['id']))
.subscribe(hero => this.hero = hero);
}
goBack(): void {
this.location.back();
}
save(): void {
this.heroService.update(this.hero)
.then(() => this.goBack());
}
}
hero-detail.component.html
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div>
<label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name" />
</div>
<button (click)="goBack()">Back</button>
<button (click)="save()">Save</button>
</div>
hero-detail.component.css
label {
display: inline-block;
width: 3em;
margin: .5em 0;
color: #607D8B;
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: .4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}
service:
hero.service.ts
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import {Hero} from "../entity/hero";
@Injectable()
export class HeroService {
private heroesUrl = 'app/heroes'; // URL to web api
private headers = new Headers({'Content-Type': 'application/json'});
//处理错误信息
private handleError(error: any): Promise<any> {
console.error('错误信息', error);
return Promise.reject(error.message || error);
}
constructor(private http: Http) { }
//获得英雄列表
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
//2秒后获得英雄列表
getHeroesSlowly(): Promise<Hero[]> {
return new Promise<Hero[]>(resolve =>
setTimeout(resolve, 2000)) // delay 2 seconds
.then(() => this.getHeroes());
}
//获得英雄
getHero(id: number): Promise<Hero> {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}
//更改
update(hero: Hero): Promise<Hero> {
const url = `${this.heroesUrl}/${hero.id}`;
return this.http
.put(url, JSON.stringify(hero), {headers: this.headers})
.toPromise()
.then(() => hero)
.catch(this.handleError);
}
//添加
create(name: string): Promise<Hero> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
//删除
delete(id: number): Promise<void> {
const url = `${this.heroesUrl}/${id}`;
return this.http.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
}