Angular學(xué)習(xí)6-路由

路由是導(dǎo)航的另一個(gè)名字腾节。路由器就是從一個(gè)視圖導(dǎo)航到另一個(gè)視圖的機(jī)制。

1.導(dǎo)航媚朦,那么我們專門做一個(gè)導(dǎo)航組件。這個(gè)組件只是導(dǎo)航使用日戈。一般導(dǎo)航的都是第一個(gè)頁面询张,而我們現(xiàn)在啟動的就是app.component.ts。
但是此頁面目前顯示的是列表涎拉,我們需要修改下瑞侮,修改成從主頁導(dǎo)航到列表頁。

那么我們?nèi)绱俗觯?br> (1)把a(bǔ)pp.component.ts文件改名為heroes.component.ts鼓拧。
(2)把AppComponent類改名為HeroesComponent(注意半火,只在這一個(gè)文件中改名)。
(3)把a(bǔ)pp-test選擇器改名為'app-my-heroes'季俩。

2.創(chuàng)建導(dǎo)航頁面钮糖,即新的app.component.ts。
新的AppComponent將成為應(yīng)用的“殼”酌住。 它將在頂部放一些導(dǎo)航鏈接店归,并且把我們要導(dǎo)航到的頁面放在下面的顯示區(qū)中。
執(zhí)行下列步驟(請嚴(yán)格按照此步驟做酪我,不能跳):
(1)創(chuàng)建一個(gè)名叫src/app/app.component.ts的新文件消痛。
(2)添加支持性的import語句。
(3)定義一個(gè)導(dǎo)出的 AppComponent類都哭。
(4)在類的上方添加@Component元數(shù)據(jù)裝飾器秩伞,裝飾器帶有app-test選擇器。
(5)將下面的項(xiàng)目從HeroesComponent移到AppComponent:
(5.1)title類屬性
(5.2)@Component模板中的<h1>標(biāo)簽欺矫,它包含了對title屬性的綁定纱新。
(5.3)在模板的標(biāo)題下面添加<app-my-heroes>標(biāo)簽,以便我們?nèi)阅芸吹接⑿哿斜怼?br> (6)添加HeroesComponent組件到根模塊的declarations數(shù)組中穆趴,以便 Angular 能認(rèn)識<app-my-heroes>標(biāo)簽脸爱。組件都需要添加到此處。
(7)添加HeroService到AppModule的providers數(shù)組中未妹,因?yàn)槲覀兊拿恳粋€(gè)視圖都需要它簿废。
(8)從HerosComponent的providers數(shù)組中移除HeroService,因?yàn)樗惶岬侥K了络它。
(9)為AppComponent添加一些import語句捏鱼。

實(shí)際文件:app.component.ts文件

import { Component } from '@angular/core';

@Component({
  selector: 'app-test',
  template: `
    <h1>{{title}}</h1>
    <my-heroes></my-heroes>//這個(gè)就是列表頁面
  `
})
export class AppComponent {
  title = 'Tour of Heroes';
}

app.module.ts文件:

import { NgModule }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule }    from '@angular/forms';

import { AppComponent }        from './app.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroesComponent }     from './heroes.component';//包含
import { HeroService }         from './hero.service';//包含

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    HeroDetailComponent,
    HeroesComponent//添加這個(gè)
  ],
  providers: [//移到此
    HeroService
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {
}

上面2步其實(shí)沒有做實(shí)際的東西,就是拆成2個(gè)組件而已酪耕,沒有做實(shí)際意義的路由的處理导梆。

3.現(xiàn)在開始處理路由:
(1)打開index.html,確保它的<head>區(qū)頂部有一個(gè)<base href="/">元素
(2)配置路由迂烁。app.module.ts中
(2.1)import { RouterModule } from '@angular/router';
(2.2)
imports: [
BrowserModule,
FormsModule, // <-- import the FormsModule before binding with [(ngModel)]
RouterModule.forRoot([//放到這里
{
path: 'heroes',
component: HeroesComponent
}
])
],
(3)修改app.component.ts的模板:
template: <h1>{{title}}</h1> <a routerLink="/heroes">Heroes</a> <router-outlet></router-outlet>//顯示路由到的組件的內(nèi)容
這樣就可以實(shí)現(xiàn)路由了看尼。

注意:這個(gè)時(shí)候模板中的routerLink的屬性值和app.module.ts中的path的關(guān)系可以看明白了。這就是路由切換了盟步,比較簡單的藏斩。

路由定義包括以下部分:
(1)Path: 路由器會用它來匹配瀏覽器地址欄中的地址,如heroes却盘。
(2)Component: 導(dǎo)航到此路由時(shí)狰域,路由器需要創(chuàng)建的組件(HeroesComponent)媳拴。

那個(gè)forroot是什么意思?下回分解兆览。
4.添加路由屈溉,其實(shí)很簡單,不信抬探,再添加一個(gè)試試子巾。
(1)添加一個(gè)新文件dashboard.component.ts然后內(nèi)容寫上:

import { Component } from '@angular/core';

@Component({
  selector: 'app-my-dashboard',
  template: '<h3>My Dashboard</h3>'
})
export class DashboardComponent { }

(2)配置新的路由:

 RouterModule.forRoot([
      {
        path: 'heroes',
        component: HeroesComponent
      },
      {
        path: 'dashboard',//添加一個(gè)這個(gè)而已
        component: DashboardComponent
      }
    ])

(3)將新的組件添加到module,這個(gè)很簡單小压,大家都應(yīng)該知道如何添加了线梗。先import { HeroesComponent } from './heroes.component';包含它,然后

 declarations: [
    HeroDetailComponent,
    HeroesComponent,
    AppComponent,
    DashboardComponent//放到這里
  ],

這樣就包含了怠益。
(4)這樣就算是準(zhǔn)備好了仪搔。再來,這個(gè)是使用:
改變app.component.ts的模板:

template: `
    <h1>{{title}}</h1>
    <a routerLink="/heroes">Heroes</a>
    <router-outlet></router-outlet>
    <a routerLink="/dashboard">Dashboard</a>
    <router-outlet></router-outlet>
  `

這樣就是兩個(gè)頁面切換了蜻牢,很簡單吧僻造。
注:上面的寫法有點(diǎn)啰嗦,可以如此寫:

template: `
    <h1>{{title}}</h1>
    <a routerLink="/heroes">Heroes</a>
    <a routerLink="/dashboard">Dashboard</a>
    <router-outlet></router-outlet>
  `

5.添加重定向孩饼,讓啟動就顯示一個(gè)組件:

 RouterModule.forRoot([
      {
        path: 'heroes',
        component: HeroesComponent
      },
      {
        path: 'dashboard',
        component: DashboardComponent
      },
      {
        path: '',//路徑是根
        redirectTo: '/dashboard',//重定向了
        pathMatch: 'full'
      }
    ])

也是很簡單的髓削。
6.美化下dashboard.component這個(gè)組件:
(1)dashboard.component.ts文件修改為:

import { Component, OnInit } from '@angular/core';

import { Hero } from './hero';
import { HeroService } from './hero.service';//包含service

@Component({
  selector: 'app-my-dashboard',
  templateUrl: './dashboard.component.html',//使用文件顯示
})
export class DashboardComponent implements OnInit {

      heroes: Hero[] = [];

      constructor(private heroService: HeroService) { }//構(gòu)造方法申明私有變量

      ngOnInit(): void {//初始化,使用承諾接口
        this.heroService.getHeroes()
          .then(heroes => this.heroes = heroes.slice(1, 5));
      }
    }

(2)添加dashboard.component.html文件镀娶,內(nèi)容如下:

<h3>Top Heroes</h3>
<div class="grid grid-pad">
  <div *ngFor="let hero of heroes" class="col-1-4">
    <div class="module hero">
      <h4>{{hero.name}}</h4>
    </div>
  </div>
</div>

美化完成了立膛。數(shù)據(jù)使用的服務(wù)的數(shù)據(jù)。

7.路由到詳情梯码,并傳遞數(shù)據(jù)宝泵。前面到詳情頁面,是使用的<app-hero-detail [hero]="selectedHero"></app-hero-detail>這種方式來傳遞對象的⌒ⅲ現(xiàn)在儿奶,我們使用路由的方式導(dǎo)航到詳情頁面,現(xiàn)在開始改造:
(1)在app.module.ts中做一個(gè)參數(shù)化的路由:

{
        path: 'detail/:id',//路徑中的冒號 (:) 表示:id是一個(gè)占位符鳄抒,當(dāng)導(dǎo)航到這個(gè)HeroDetailComponent組件時(shí)闯捎,它將被填入一個(gè)特定英雄的id。
        component: HeroDetailComponent
      }

(2)改造hero-detail.component.ts為:

// Keep the Input import for now, you'll remove it later:
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { Location } from '@angular/common';

import { HeroService } from './hero.service';
import 'rxjs/add/operator/switchMap';
import { Hero } from './hero';


@Component({
    selector: 'app-hero-detail',
    templateUrl: './hero-detail.component.html',//模板變化
  })

export class HeroDetailComponent implements OnInit {
    constructor(
        private heroService: HeroService,
        private route: ActivatedRoute,
        private location: Location
      ) {}

      @Input() hero: Hero;

      ngOnInit(): void {
        this.route.paramMap
          .switchMap((params: ParamMap) => this.heroService.getHero(+params.get('id')))
          .subscribe(hero => this.hero = hero);
      }

      goBack(): void {
        this.location.back();//利用瀏覽器的歷史堆棧许溅,導(dǎo)航到上一步
      }
}

switchMap運(yùn)算符如何將可觀察的路由參數(shù)中的 id 映射到一個(gè)新的Observable瓤鼻, 即HeroService.getHero()方法的結(jié)果。

如果用戶在 getHero 請求執(zhí)行的過程中再次導(dǎo)航這個(gè)組件贤重,switchMap 再次調(diào)用HeroService.getHero()之前茬祷, 會取消之前的請求。

英雄的id是數(shù)字并蝗,而路由參數(shù)的值總是字符串祭犯。 所以我們需要通過 JavaScript 的 (+) 操作符把路由參數(shù)的值轉(zhuǎn)成數(shù)字秸妥。
(3)在hero.service.ts中添加:
···
getHero(id: number): Promise<Hero> {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}//根據(jù)ID獲取到信息
···
(4)添加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>
</div>
···
(5)點(diǎn)擊時(shí),需要切到detail頁面沃粗,需要改造dashboard.component.html粥惧,能夠點(diǎn)擊和傳遞參數(shù):

<h3>Top Heroes</h3>
<div class="grid grid-pad">
    <a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">//這里就是能夠點(diǎn)擊,并且傳遞了參數(shù)
        <div class="module hero">
            <h4>{{hero.name}}</h4>
        </div>
    </a>
</div>

現(xiàn)在就可以用路由的方式導(dǎo)航到detail頁面了陪每。還能傳遞參數(shù)呢影晓。

8.上面雖然可以使用了镰吵,但是路由的代碼太多檩禾,讓app.module.ts會越變越大,因此疤祭,需要將路由提取到一個(gè)單獨(dú)的文件盼产。
(1)做一個(gè)單獨(dú)的文件: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';

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 {}

(2)修改app.module.ts勺馆,以便包含這個(gè)路由:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here

import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroesComponent } from './heroes.component';
import { DashboardComponent } from './dashboard.component';
import { HeroService } from './hero.service';

import { AppRoutingModule } from './app-routing.module';//1戏售、包含它

@NgModule({
  imports: [
    BrowserModule,
    FormsModule, // <-- import the FormsModule before binding with [(ngModel)]
    AppRoutingModule//2.放到此,添加模塊
  ],
  declarations: [
    HeroDetailComponent,
    HeroesComponent,
    AppComponent,
    DashboardComponent,
  ],
  bootstrap: [ AppComponent ],
  providers: [HeroService]
})
export class AppModule { }

通過上面2步草穆,就將路由單獨(dú)列出了灌灾。

9.也可以通過代碼跳轉(zhuǎn)到詳細(xì)頁面,當(dāng)然也是路由的方式悲柱。
(1).將heroes.component.ts中模板中的:
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
替換成一個(gè)按鈕:

<div *ngIf="selectedHero">
  <h2>
    {{selectedHero.name | uppercase}} is my hero
  </h2>
  <button (click)="gotoDetail()">View Details</button>//這個(gè)按鈕
</div>

(2)在類中:

import { Router } from '@angular/router';//1.包含

constructor(
    private router: Router,
    private heroService: HeroService) { }//2.構(gòu)造函數(shù)中申明

 gotoDetail(): void {
    this.router.navigate(['/detail', this.selectedHero.id]);//3.使用代碼跳轉(zhuǎn)
  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锋喜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豌鸡,更是在濱河造成了極大的恐慌嘿般,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涯冠,死亡現(xiàn)場離奇詭異炉奴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蛇更,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門瞻赶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人派任,你說我怎么就攤上這事共耍。” “怎么了吨瞎?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵痹兜,是天一觀的道長。 經(jīng)常有香客問我颤诀,道長字旭,這世上最難降的妖魔是什么对湃? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮遗淳,結(jié)果婚禮上拍柒,老公的妹妹穿的比我還像新娘。我一直安慰自己屈暗,他們只是感情好拆讯,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著养叛,像睡著了一般种呐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弃甥,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天爽室,我揣著相機(jī)與錄音,去河邊找鬼淆攻。 笑死阔墩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瓶珊。 我是一名探鬼主播啸箫,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伞芹!你這毒婦竟也來了忘苛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤丑瞧,失蹤者是張志新(化名)和其女友劉穎柑土,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绊汹,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡稽屏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了西乖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狐榔。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖获雕,靈堂內(nèi)的尸體忽然破棺而出薄腻,到底是詐尸還是另有隱情,我是刑警寧澤届案,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布庵楷,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏尽纽。R本人自食惡果不足惜咐蚯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弄贿。 院中可真熱鬧春锋,春花似錦、人聲如沸差凹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽危尿。三九已至呐萌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脚线,已是汗流浹背搁胆。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工弥搞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邮绿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓攀例,卻偏偏與公主長得像船逮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子粤铭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Angular 2架構(gòu)總覽 - 簡書http://www.reibang.com/p/aeb11061b82c A...
    葡萄喃喃囈語閱讀 1,486評論 2 13
  • 版本:4.0.0+2 有一些英雄指南應(yīng)用的新需求: 添加一個(gè)儀表盤 視圖挖胃。 添加在英雄 視圖和 儀表盤 視圖之間導(dǎo)...
    soojade閱讀 1,303評論 0 0
  • Angular 2是一個(gè)幫助我們使用HTML和JavaScript構(gòu)建客戶端應(yīng)用的框架。這個(gè)框架包含幾個(gè)互相協(xié)作的...
    JasonQiao閱讀 7,125評論 1 48
  • 簡要說明:本文主要摘錄于 Angular 官網(wǎng)中 JavaScript 的設(shè)計(jì)風(fēng)格指南梆惯。本風(fēng)格指南介紹了提倡的約定...
    _仲夏_閱讀 1,050評論 0 2
  • 詩與詩人· 田 秀詩和詩人有什么好談的,我也不知道我為啥選這個(gè)題目.想來想去,還是有談的,特別實(shí)詩人在詩里究竟是什...
    興安居士閱讀 228評論 0 3