学过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); } }