Angular2初级篇之路由

这篇博客介绍了Angular2中的路由概念,将其视为导航的手段,详细阐述了如何创建模块组件、设置路由、添加路由插座以及实现参数化路由来跳转英雄详情。通过实例解析了在app-routing.module.ts和app.component.ts中的关键步骤,同时提到了所需的文件,包括英雄实体类、heroes、dashboard、hero-detail和service。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


学过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>标签添加到模板的底部。 RouterOutletRouterModule提供的指令之一。 当我们在应用中导航时,路由器就把激活的组件显示在<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中添加英雄跳转

{path: 'detail/:id',component: HeroDetailComponent}
注意:路径中的冒号 (:) 表示 :id是一个占位符,当导航到这个 HeroDetailComponent组件时,它将被填入一个特定英雄的id。路由参数的值 总是字符串

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


以上就是所需要的文件,还有些知识没说到 路由的动态链接、调用服务并使用、点击事件、数据绑定、OnInit、=>的使用、管道 ,有需要的可以自己查看 Angular2路由


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值