上一篇:Angular2入門系列教程5-路由(一)-使用簡單的路由並在在路由中傳遞參數
之前介紹了簡單的路由以及傳參,這篇文章我們將要學習復雜一些的路由以及傳遞其他附加參數。一個好的路由系統可以使我們的程序更好的工作。
假設你已經跟上了我們的進度。
我們來為我們的文章明細新增一個評論框;當我們在明細中點擊評論的時候,在我們的明細頁面顯示評論,這里,我們就可以完全把明細頁面看成一個獨立的路由,可以建立自己的子路由頁面,做一些評論,分享等操作。
那,首先在data目錄下建立我們的評論實體Commen和評論服務Comment.service

1 export class Comment{ 2 id:number; 3 userName:string; 4 content:string; 5 blogId:number; 6 }

1 import {Comment} from './comment' 2 export let Comments:Comment[]=[]; 3 export class CommentService 4 { 5 public AddComment(com:Comment) 6 { 7 com.id=this.GetMaxId(); 8 Comments.push(com); 9 } 10 public GetBlogComments(blogId:number):Comment[] 11 { 12 return Comments.filter(x=>x.blogId==blogId); 13 } 14 private GetMaxId():number 15 { 16 var maxId=1; 17 Comments.forEach(x=>{ 18 if(x.id>maxId) 19 maxId=x.id; 20 }); 21 return maxId; 22 } 23 }
作為服務,我們的commen.service提供了獲取相應博客的評論以及添加評論的功能!然后我們在app.module.ts中的provider數組中添加我們的CommnetService服務類
那么,數據准備好了,現在我們來建立我們的評論頁面
在App文件夾下建立以下東西(希望你是用插件直接生成,這樣可以節約很多時間,插件可以幫我們直接初始化這些組件,這樣我們可以直接使用而不報錯),但是我們先去處理路由問題,讓我們可以在articleDetai中直接導航到這個組件
之前我們談到的路由是要用<router-outlet></router-outlet>去顯示組件,我們自然要在article.detail.html中添加這么一句話
然后為了我們能找文章明細中進行,導航,我們需要配置一下路由文件。這次,我們新建一個路由配置文件,我推薦這樣做,因為,我們的程序始終是分模塊的,不同模塊用自己的路由就行了,而不是所有的路由都配置在一個文件中
我們在根目錄(app.routing同級)下面建立articleDetail.routing.ts,鍵入一下代碼

1 import { NgModule } from '@angular/core'; 2 import { RouterModule, Routes } from '@angular/router'; 3 4 import { CommentComponent } from './comment/comment.component'; 5 import { ArticledetailComponent } from './articledetail/articledetail.component'; 6 7 const articleDetailRoutes: Routes = [ 8 { 9 path: 'articledetail/:id', 10 component: ArticledetailComponent, 11 children: [ 12 { 13 path: 'comment', 14 component: CommentComponent 15 } 16 ] 17 } 18 ]; 19 @NgModule({ 20 imports: [ 21 RouterModule.forChild(articleDetailRoutes) 22 ], 23 exports: [ 24 RouterModule 25 ] 26 }) 27 export class ArticleDetailRoutingModule { }
我們看到有個children的節點,這個就是我們配置路由子節點的地方
然后我們將app.routing.ts中關於articledetail的路由刪掉

1 const routes:Routes=[ 2 { path: 'article',component: ArticleComponent}, 3 { path: '',redirectTo:"/article",pathMatch: 'full'} 4 ];
然后,我們在app.moudule.ts中添加本次路由相關的信息

1 import { BrowserModule } from '@angular/platform-browser'; 2 import { NgModule } from '@angular/core'; 3 import { FormsModule } from '@angular/forms'; 4 import { HttpModule } from '@angular/http'; 5 import { AppRoutingModule } from './app.routing'; 6 import { ArticleDetailRoutingModule } from './articledetail.routing'; 7 8 import {BlogService} from './data/blog.service'; 9 import {CommentService} from './data/comment.service'; 10 11 import { AppComponent } from './app.component'; 12 import { ArticleComponent } from './article/article.component'; 13 import { ArticledetailComponent } from './articledetail/articledetail.component'; 14 import { CommentComponent } from './comment/comment.component'; 15 16 17 @NgModule({ 18 declarations: [ 19 AppComponent, 20 ArticleComponent, 21 ArticledetailComponent, 22 CommentComponent 23 24 ], 25 imports: [ 26 BrowserModule, 27 FormsModule, 28 HttpModule, 29 ArticleDetailRoutingModule, 30 AppRoutingModule 31 32 ], 33 providers: [BlogService,CommentService], 34 bootstrap: [AppComponent] 35 }) 36 export class AppModule { }
路由可以用了,我們現在來到articleDetail組件,具體編寫一下怎么路由
在html中添加代碼
<button class="btn" (click)="doComment()">評論</button>
然后在ts中編寫事件
doComment() { this.router.navigate(["comment"],{relativeTo:this.aRoute}); }
好了,一切准備就緒,現在,我們的子路由可以用了,如果不出意外,點擊評論按鈕,你可以看到以下內容
到此,我們實現了多級路由,那么,現在來看看傳遞復雜參數,那,我們就把我們的博客的標題和id傳過去吧
在articleDetail組件中的doComment編寫
doComment() { this.router.navigate(["comment",{id:this.blog.id,title:this.blog.title}],{relativeTo:this.aRoute}) }
我們這里處理了兩個參數,[]中"comment"表示要導航到的路由,{}里面的內容是我們傳遞的參數;relativeTo表示相對與aRoute的路徑,我們先來看看這樣做的效果
我們看到,在我們的地址欄,路由之外,用分號分割了我們傳遞的參數,這就是Angular2路由中傳遞參數的方式,之后我們要做的就是在我們的Comment里面接收這些參數,這里直接貼出我們的Comment組件的完整代碼
comment.component.ts

1 import { Component, OnInit,Input } from '@angular/core'; 2 import {ActivatedRoute,Params,Router} from '@angular/router'; 3 import { Location } from '@angular/common'; 4 5 import {Comment} from '../data/comment'; 6 import {CommentService} from '../data/comment.service'; 7 8 import 'rxjs/add/operator/switchMap'; 9 10 @Component({ 11 selector: 'comment', 12 templateUrl: './comment.component.html' 13 }) 14 15 export class CommentComponent implements OnInit { 16 BlogTitle:string; 17 private comments:Comment[]; 18 private com:Comment=new Comment(); 19 private blogId:number; 20 constructor( 21 private cService: CommentService, 22 private aRoute: ActivatedRoute, 23 private router: Router, 24 private location: Location 25 ){} 26 ngOnInit() { 27 let id=this.aRoute.params 28 .subscribe(params=>{ 29 this.comments=this.cService.GetBlogComments(+params["id"]); 30 this.blogId=+params["id"]; 31 this.BlogTitle=params["title"]; 32 }) 33 } 34 sumComment() 35 { 36 if(this.com.userName&&this.com.content) 37 { 38 this.com.blogId=this.blogId; 39 this.cService.AddComment(this.com); 40 this.comments=this.cService.GetBlogComments(this.blogId); 41 console.log(this.comments); 42 this.com=new Comment(); 43 } 44 } 45 }
html

1 <div class="container"> 2 <h2>Blog: {{BlogTitle}}</h2> 3 <div class="comment"> 4 <div class="section"> 5 <div *ngFor="let com of comments"> 6 <div> 7 <span>名字:</span> 8 <span>{{com.userName}}</span> 9 </div> 10 <div > 11 <span>評論內容:</span> 12 <span>{{com.content}}</span> 13 </div> 14 <div class="divider"></div> 15 </div> 16 </div> 17 </div> 18 <div class="divider red"></div> 19 <div> 20 <div class="section"> 21 <div class=""> 22 來,評論一下 23 </div> 24 <div> 25 <input type="text" placeholder="你的名字" [(ngModel)]="com.userName" class=""> 26 <input type="text" placeholder="說點兒什么" [(ngModel)]="com.content" class=""> 27 </div> 28 <div> 29 <button class="btn" (click)="sumComment()">提交</button> 30 </div> 31 </div> 32 </div> 33 </div>
我們直接在代碼里面通過route的params屬性獲取了路由參數,然后處理它;這里的params是一個Observable類型的,我們直接調用它的Subscribe方法(以后再介紹),獲取到params,通過一些操作,將這些數據獲取出來,顯示在頁面上,我們來看看我們做的效果
這就是我們本篇文章的內容!
也許,許多人會問了,我們可以直接在這里傳遞一個類的數據么,比如我們就直接傳遞blog:this.blog ,把整個Blog傳遞過去,那我只能告訴不可以,為什么?我們來看看Angular2路由參數的定義吧
這里的定義是key:string,也就是,我們的參數只能傳遞string類型的過去
我們並不推薦用這種方式傳遞很多參數到子組件中去,我們可以采用其他方式,比如localStorage;如果你非要這么做,也有解決方法,用JSON.stringify將你的類變成json字符串,到子組件接收之后,再用JSON.parse重新變成一個Object!(很蠢不是么?)
關於路由暫時就介紹這么多,Angular2有更多關於路由的知識,有興趣的同學可以直接到官網去看,或者,我把這個系列寫完了再回頭寫一個!在我看來,我們日常開發用不到那么多東西,就不在這里介紹了
更新ing。。。
項目已經放到了gitbub上,地址 https://github.com/SeeSharply/LearnAngular
本文章的提交 https://github.com/SeeSharply/LearnAngular/tree/8021af04eb463c31c110e058753ab19d918391af