上一篇文章我們將Angular2的數據服務分離出來,學習了Angular2的依賴注入,這篇文章我們將要學習Angualr2的路由
為了編寫樣式方便,我們這篇文章開始引入第三方的css庫materializecss,引入方法直接在index.html中普通引用就可以了
眾所周知,Angular出現的目的就是解決web編程的一些限制,讓我們編寫的網頁能像App一樣運作,我們現在稱之為單頁面應用(SPA),單頁面應用程序有諸多好處,譬如頁面響應快,良好的前后端分離,對服務器壓力小等等,當然也有不利於SEO等缺點。
而實現SPA最重要的那當然是路由,Angular2提供的路由可以讓我們在頁面間隨意的切換而不用刷新頁面,下面開始我們的路由之旅
假設你已經跟上了我們的進度,那就在src/app目錄下建立一個app.routing.ts的文件,代碼如下
import {RouterModule,Routes} from "@angular/router"; import {NgModule} from "@angular/core"; import { AppComponent } from './app.component'; import { ArticleComponent } from './article/article.component'; import { ArticledetailComponent } from './articledetail/articledetail.component'; const routes:Routes=[ { path: 'home',component: AppComponent}, { path: 'article',component: ArticleComponent}, { path: 'articledetail/:id',component: ArticledetailComponent}, { path: '',redirectTo:"/home",pathMatch: 'full'} ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
讓我們來看看這個app.routing.ts干了什么事情
首先我們需要使用語句 import {RouterModule,Routes} from "@angular/router"; 導入我們的路由模塊RouterModule以獲取路由的支持,然后導入了Routes,這是一個路由的配置數組,我們需要使用它來配置我們的路由
接下來我們將我們的組件都導入了進來,使用一個Routes類型的變量去配置路由,方式就如上所寫,其中我們看到{ path: 'articledetail:id',component: ArticledetailComponent},中的id,這種路由的訪問鏈接就是http://****.com/articledetail/id
最后,我們使用NgModule裝飾器去描述導入和導出的情況,這樣,我們的路由表就配置好了,只要在app.module.ts中導任意就可以使用了,順便細心的朋友可能發現了,我們將BlogService也放到這里去,這樣,我們在任意地方都可以使用BlogService了。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppRoutingModule } from './app.routing'; import {BlogService} from './data/blog.service'; import { AppComponent } from './app.component'; import { ArticleComponent } from './article/article.component'; import { ArticledetailComponent } from './articledetail/articledetail.component'; @NgModule({ declarations: [ AppComponent, ArticleComponent, ArticledetailComponent ], imports: [ BrowserModule, FormsModule, HttpModule, AppRoutingModule ], providers: [BlogService], bootstrap: [AppComponent] }) export class AppModule { }
那么具體要怎么使用路由呢?
上面配置顯示我們將AppComponent組件作為了路由起點,那我們就在這個組件里面做些事情
App.Component.html
<div class="container"> <a routerLink="/article" class="btn waves-effect waves-light">博客列表</a> <a routerLink="/articledetail/1" class="btn waves-effect waves-light">最多閱讀</a> </div> <router-outlet></router-outlet>
我們看到有兩個新東西,一個是routerLink,這個就像我們原本的a標簽的href,是指定Angular路由的一個東西
第二個就是router-outlet標簽,這個是個導航容器,導航過后,新的組件將會在這里展現
修該過后,我們需要修改articleDetailComponent的代碼以支持路由傳參的id
articldetail.component.ts
import { Component, OnInit,Input } from '@angular/core'; import {ActivatedRoute,Params} from '@angular/router'; import { Location } from '@angular/common'; import {BLOGS,Blog} from '../data/blog'; import {BlogService} from '../data/blog.service' import 'rxjs/add/operator/switchMap'; @Component({ selector: 'article-detail', templateUrl: './articledetail.component.html', styleUrls:['./articledetail.component.css'] }) export class ArticledetailComponent implements OnInit { @Input() blog:Blog; constructor( private bService: BlogService, private route: ActivatedRoute, private location: Location ) {} ngOnInit() { let id=this.route.params .switchMap((params: Params) => params['id']) .subscribe(x=>this.blog=this.bService.getSelectedBlog(+x)) } back() { this.location.back(); } }
我們添加了ActivatedRoute,Params用以獲取路由參數,由於Angular的路由參數是一個Observable對象,我們使用switchMap去處理它,你現在不用去關心這些,因為,在之后的學習中,我們會專門學習Observable
然后我們添加了一個返回方法,點擊就可以返回上一級
看html代碼
<div class="articledetail" *ngIf="blog"> <h2>文章明細</h2> <div class="content"> <div class="row"> <span >ID</span> <span>{{blog.id}}</span> </div> <div class="row"> <span >Title</span> <input type="text" class="myInput" [(ngModel)]="blog.title"/> </div> <div class="row"> <button class="btn" (click)="back()">返回列表</button> </div> </div> </div>
這樣,我們的明細就可以顯示了。
程序到此還不完全,我們當然還要處理下ArticleComponnet組件,改動很少,只用改動一點兒html代碼就行了
article.component.html
<div class="article">
<ul class="articleList">
<li *ngFor="let blog of blogList" [routerLink]="['/articledetail',blog.id]" >
<a>
{{blog.id}}:{{blog.title}}
</a>
</li>
</ul>
<div>
</div>
這里使用的[routerLink]=[]的方式,第一個是路由地址,第二個是參數,就是我們的id
處理完了,我們可以來看看效果了
看到這里,你是否覺得有點。。。生硬,那么我們來為路由加一點兒動畫
我們只處理下articleDetail組件
import { Component, OnInit,Input ,HostBinding, trigger, transition, animate, style, state } from '@angular/core'; import {ActivatedRoute,Params} from '@angular/router'; import { Location } from '@angular/common'; import {BLOGS,Blog} from '../data/blog'; import {BlogService} from '../data/blog.service' import 'rxjs/add/operator/switchMap'; @Component({ selector: 'article-detail', templateUrl: './articledetail.component.html', styleUrls:['./articledetail.component.css'], animations: [ trigger('routeAnimation', [ state('*', style({ opacity: 1, transform: 'translateX(0)' }) ), transition(':enter', [ style({ opacity: 0, transform: 'translateY(-100%)' }), animate('0.2s ease-in') ]), transition(':leave', [ animate('.5s ease-out', style({ opacity: 0, transform: 'translateY(100%)' })) ]) ]) ] }) export class ArticledetailComponent implements OnInit { @HostBinding('@routeAnimation') get routeAnimation() { return true; } @HostBinding('style.display') get display() { return 'block'; } @HostBinding('style.position') get position() { return 'absolute'; } @Input() blog:Blog; constructor( private bService: BlogService, private route: ActivatedRoute, private location: Location ) {} ngOnInit() { let id=this.route.params .switchMap((params: Params) => params['id']) .subscribe(x=>this.blog=this.bService.getSelectedBlog(+x)) } back() { this.location.back(); } }
這里不打算講解Animate,因為,之后我們會專門介紹Angular2的動畫
現在這里放一個空的鏈接:Angular2入門系列教程:Angular2動畫
來看看效果吧
文章的介紹就到這里,有疑問可以給我留言
更新ing。。。
項目已經放到了gitbub上,地址 https://github.com/SeeSharply/LearnAngular
本文章的提交 https://github.com/SeeSharply/LearnAngular/tree/bba4d45b63621a7fc8fd556aa1fc49d397a00552