Angular2 - Starter - Routes, Route Resolver

在基於Angualr的SPA中,路由是一個很重要的部分,它幫助咱們更方便的實現頁面上區域的內容的動態加載,不一樣tab的切換,同時及時更新瀏覽器地址欄的URN,使瀏覽器回退和前進能導航到歷史訪問的頁面。javascript

(1) 基本配置css

1.1.配置base hrefhtml

在配置RoutesModule以前,咱們須要再index.html裏配置base href,這樣,每個路由的路徑的前綴都是base href,應用的圖片,文件夾,樣式等資源都經過該base href來定位。java

//index.html
<base href='/'></base>

  

1.2.配置應用路由bootstrap

//app.routes.ts
export const ROUTES: Routes = [ //根路徑,經過base url:127.0.0.1:8888訪問LogOnComponent, { path: '', component: LogOnComponent }, { path: 'chats', component: ChatsComponent }, { path: 'logon', component: LogOnComponent }, { path: 'fresh', component: FreshComponent }, /*base url下的路由,若是在初始化路由時使用hash:經過127.0.0.1:8888/#/friends訪問 若是不使用hash,則經過127.0.0.1:8888/friends訪問 */ { path: 'friends',component: FriendsComponent }, { path: 'other', //在訪問127.0.0.1:8888/#/other時,再去加載一個模塊,這就加快了應用初始化的速度 loadChildren: () => System.import('./components/sections/+detail') .then((comp: any) => comp.default), }, /*在跳轉到任何一個路由以前會實例化該組件,若成功(找到目標路由),則跳轉到目標路由 若失敗,則跳轉到 NoContentComponent ,咱們能夠將它理解爲錯誤路由時須要跳轉到的位置 */ { path: '**', component: NoContentComponent }, ];

  

1.3.在應用模塊中加載路由瀏覽器

//app.module.ts
import { ROUTES } from './app.routes'; import {RouterModule, NoPreloading} from '@angular/router'; @NgModule({ bootstrap: [ AppComponent ], imports: [ /*使用RouterModule.forRoot方法將路由配置加載到base url, useHash:true,則urn在瀏覽器顯示爲http://127.0.0.1:8083/#/friends useHash:false,則urn在瀏覽器顯示爲http://127.0.0.1:8083/friends 但其實,angular路由跳轉都不會刷新整個頁面,而是動態加載各個模塊 enableTracing:true,在瀏覽器的輸出窗口輸出當前跳轉操做的詳細信息,如: NavigationEnd(id: 2, url: '/friends', urlAfterRedirects: '/friends'), preloadingStrategy: NoPreloading,容許組件懶加載,當應用加載成功以後,加載器便監聽懶加載的路由的訪問事件,一旦訪問就去加載對應組件或模塊 */ RouterModule.forRoot(ROUTES, { useHash: false,enableTracing:false, preloadingStrategy: NoPreloading }) ] })

  

(2) 子模塊的路由app

2.1 創建子模塊異步

//detail.module.ts
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { DetailComponent } from './detail.component';
import { FeedbackComponent } from '../../parts/feedback';
import { FeedbackRoutingModule } from './routing/feedback-routing.module';
import {AboutComponent} from "../about/about.component";
//裝飾一個NgModule
@NgModule({
  declarations: [
//引入該子模塊的組件
    DetailComponent,
    FeedbackComponent,
    AboutComponent
  ],
  imports: [
//此處導入CommonModule,而不是app.module中使用的BrowserModule,
//若是BrowserModule被導入,就會報以下錯誤,可見BrowserModule用於加載根模塊,CommonModule用於在懶加載的模塊中提供angular的基本指令
/*Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
*/
    CommonModule,
    FormsModule,
//導入路由模塊
    FeedbackRoutingModule
  ]
})
export default class OtherModule {

}

  

2.2 創建子應用模塊的路由模塊ide

//detail-routing.module.ts
import { ROUTES } from './feedback-routing.routes'; @NgModule({ imports:[ //使用RouterModule.forChild加載子路由模塊 RouterModule.forChild(ROUTES) ], exports:[ //導出的DetailRoutingModule 中攜帶一個加載了ROUTES的RouterModule RouterModule ], providers:[ PeopleSvc, //到如一些做爲服務的提供商 MemberShipResolver ] }) export class DetailRoutingModule{}

  

2.3 配置子模塊內部的路由this

//detail-routing.routes.ts
import { Routes } from '@angular/router';
import { FeedbackComponent } from '../../../../components/parts/feedback';
import { DetailComponent } from '../detail.component';
import { AboutComponent } from '../../about/about.component';
import { MemberShipResolver } from '../../../../services/membership-resolver.service';
export const ROUTES:Routes = [
  {
//應用子模塊路徑
    path:'',
    data:{title:'Other'},
    component:DetailComponent,
    outlet:'primary',
    resolve: {
      pageInfo: MemberShipResolver
    },
//子路由
    children:[
      { path:'logon',redirectTo:'' },
      {
        path: 'feedback',
        component: FeedbackComponent,
/*定義實例化FeedbackComponent時的數據,可經過當前的ActivatedRoute對象來訪問到 this.route.data.getValue()
*/
        data:{title:'User feedback'} ,
        resolve: {
          userInfoResult: MemberShipResolver
        }
      },
      {
        path:'about',
        component:AboutComponent
      }
    ]
  }
];

  

(3) 路由分析器

Router Resolver實際上是一個服務,在跳轉到某個路由時,該service可獲取到當前ActivatedRoute,獲取其攜帶的data,這裏能夠提早去服務端獲取一些數據,或者作一些數據轉換以後再進行組件的實例化和渲染。好比,當用戶將要跳轉到應用的反饋頁面填寫反饋時,咱們能夠經過一個membership-resolver去檢查是否爲登陸用戶,若是不是,則跳轉到登陸頁面,若是是則顯示歷史反饋和反饋填寫表單入口。

3.1 創建membership-resolver

//membership-resolver.service.ts
import { Injectable } from '@angular/core';
import { FeedbackSvc } from './feedbackSvc';
import {Router, RouterStateSnapshot, ActivatedRouteSnapshot, Resolve} from "@angular/router";
import {ClientState} from "./client-state.service";
@Injectable()
export class MemberShipResolver implements Resolve<string>{
//clientState:ClientState 該服務提供當前登陸用戶的信息
  constructor(private router: Router,private peopleSvc:PeopleSvc,private clientState:ClientState)  {


  }

//實現 Resolve接口的resolve方法
resolve(route:ActivatedRouteSnapshot,state:RouterStateSnapshot):Promise<string>{
    let me = this;
    let clientUser = this.clientState.get('user');
    let prom = new Promise(function(resolve,reject){
//若是當前登陸用戶爲null,則跳轉到logon
      if(clientUser === null){
        me.router.navigate(['./logon']);
        resolve(null);
      }else{
//獲取全部feedback
        me.feedbackSvc.getAll().then((data)=>{
          if(data !== null){
            resolve(data);
          }else{
            resolve(null);
          }
        });
      }
    });
    return prom;
  }
}

  

 

3.2 制定分析器解析的數據標識

//feedback.routing.ts
{ path: 'feedback', component: FeedbackComponent, data:{title:'User feedback'} , resolve: { //定義feedbackResult的分析器,該分析器異步返回的數據將添加到data下 feedbackResult: MemberShipResolver } }

  

3.3 監控分析器數據變化

//feedback.component.ts
import { Component } from '@angular/core';
import { FeedbackSvc } from './feedbackSvc';
import {Router, ActivatedRoute} from "@angular/router";
import {Feedback} from "../../../models/business/Feedback";
import {User} from "../../../models/business/User";
import {ClientState} from "../../../services/client-state.service";
@Component({
  selector:'feedback',
  templateUrl:'feedback.component.html',
  styleUrls:[ 'feedback.component.css' ],
  providers:[ FeedbackSvc ]
})

export class FeedbackComponent{
  private allFeedback:Feedback[] = [];
  constructor(public feedbackSvc:FeedbackSvc, private router: Router,private route:ActivatedRoute,private client:ClientState){

  }


  ngOnInit() {
    let _this = this;
//註冊當前路由攜帶的數據的變化回調
    this.route.data.subscribe((data:Feedback[]) => {
      if(data !== null){
//將分析器返回的數據做爲component的數據
        _this.allFeedback = data;
      }
    });
  }
}
相關文章
相關標籤/搜索