1. 程式人生 > >Angular2入門系列教程6-路由(二)-使用多層級路由並在在路由中傳遞複雜引數

Angular2入門系列教程6-路由(二)-使用多層級路由並在在路由中傳遞複雜引數

  之前介紹了簡單的路由以及傳參,這篇文章我們將要學習複雜一些的路由以及傳遞其他附加引數。一個好的路由系統可以使我們的程式更好的工作。

  假設你已經跟上了我們的進度。

  我們來為我們的文章明細新增一個評論框;當我們在明細中點選評論的時候,在我們的明細頁面顯示評論,這裡,我們就可以完全把明細頁面看成一個獨立的路由,可以建立自己的子路由頁面,做一些評論,分享等操作。

  那,首先在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中新增程式碼

1

<button class="btn" (click)="doComment()">評論</button>

  然後在ts中編寫事件

1

2

3

4

doComment()

{

this.router.navigate(["comment"],{relativeTo:this.aRoute});

}

  好了,一切準備就緒,現在,我們的子路由可以用了,如果不出意外,點選評論按鈕,你可以看到以下內容

  

到此,我們實現了多級路由,那麼,現在來看看傳遞複雜引數,那,我們就把我們的部落格的標題和id傳過去吧

在articleDetail元件中的doComment編寫

1

2

3

4

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。。。