Angular 2 + 折騰記 :(4)初步瞭解路由及使用

CRPER發表於2017-03-28

前言

路由這塊的水挺深,我這裡扯扯我用過的一些特性及一丟丟的經驗


概念性的東西

言簡意賅的總結一下:

路由就是控制檢視與檢視之間的跳轉,之間還可以傳遞引數什麼的,路由的退後及前進不會完整的請求整個頁面,還可以完全不請求(在生命週期裡面控制);

  • angular 2 + 裡面有兩種url風格
    • 一個是常規我們訪問url那種protocol://domain/path/f/fds
    • 一種的hash(#)風格,protocol://domain/#/account/login
  • 可以操控路由了,那必然就可以做鑑權了。。。

  • 路由相關的指令或者術語

    • <router-outlet> :路由佔位符,可以理解為渲染路由元件的區域,一個元件只能一個無命名<router-outlet>,命名的可以多個
    • ng-content: 可以巢狀一個元件的內容在另外一個元件中!!很常用!
    • RouterLink:可以讓一個元素具有跳轉功能,裡面有很多使用的引數[指令],我大體解釋下常用的哈
      • queryParams : 可以傳遞引數的,跳轉過去就是這種/security-alert?AlertType=50,可以接受物件
      • skipLocationChange : 內容跳轉,路由保持不變,換句話說,就是停留在上個頁面的url而不是新的url -- 常用!
      • fragment:程式碼片段拼接到url,只接受字串,在url就是hash拼接;/security-alert#1232
    • ActivatedRoute: 當前活動的路由,非常常用,邏輯處理的時候經常用到,引數比上面多,大同小異
    • ActivatedRouteSnapshot:這個是上面的區域性實現,路由映象,用來獲取一些路由的資訊很方便,單獨用上面的也可以拿到相關的路由資訊
    • Router這個內建元件,是路由最重要的東東了,相對路由這些,絕對路徑這些都可以實現,我這裡也說說常用的
      • url: 獲取url
      • routerState: 路由狀態
      • navigateByUrl:絕對路徑的跳轉,有個可選引數[{relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling,}?: NavigationExtras],可選引數就是上面那個停留在當前路徑跳轉這些
      • parseUrl:格式化url,實用!
      • navigate :配合可選引數可以實現當前路勁下的相對跳轉,帶引數跨頁面跳轉等

angular 4版本的路由加強了很多。。比如可以在路由進入或者脫離的時候做一些事件處理!!!,具體可以去看API的改動


常規路由

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 頁面元件
import { NameComponent } from './name.component';

const routes: Routes = [
  { 
    path: 'path', // path是路由訪問的路徑
    component: NameComponent, //component是對映的元件
    children:[ // children是巢狀元件的包含層
        {
            path:'', //留空可以讓路徑預設指向第一個元件,訪問時候沒有帶任何子路徑情況下
            component:'ffff' // 對應的元件記得先提前引入
        },
        {
            path:'edit/:id', // 這樣是代表子元件需要帶一個引數才能進入
            component:'ggg' // 對應的元件記得先提前引入
        }
    ]
  } 

];

@NgModule({
  // 注入到模組中,forChild只能用於子模組,forRoot只能用於跟模組
  // forRoot有一個可選的配置引數,裡面有四個選項
  // enableTracing :在console.log中列印出路由內部事件資訊
  // useHash :把url改成hash風格,protocol://domain/#/account/login
  // initialNavigation : 禁用初始導航,沒用過。。
  // errorHandler :使用自定義的錯誤處理,來丟擲報錯資訊;
  imports: [RouterModule.forChild|Root(routes)], 

  // exports是匯出元件,一般用於自定義元件或者模組。。
  exports: [RouterModule],
})複製程式碼

懶載入

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

// 路由相關模組
import { Routes, RouterModule } from '@angular/router';

// 佈局
import { MitLayoutComponent } from './widgets/mit-layout/mit-layout.component';

// 鑑權服務
import { RbacService } from './rbac/rbac.service';

const routes: Routes = [
  {
    path: '',
    redirectTo: '/page/dashboard/vehicle-overview',
    pathMatch: 'full', // 匹配全域性,預設是'prefix','full'是全域性匹配/
    canActivate: [RbacService] // canActivate是內建攔截器,RbacService是鑑權服務
  },
  {
    path: 'page',
    component: MitLayoutComponent,
    canActivate: [RbacService],
    children: [ // 懶載入在目前的版本都必須用絕對路徑指向對應的模組,dashboard.module是檔名,#DashboardModule是裡面到處的模組,必須緊跟才能正確識別
      { path: 'base-data', loadChildren: 'app/modules/base-data/base-data.module#BaseDataModule' }, // 基礎資料
  },
  {  // 賬號相關
    path: 'account',
    loadChildren: 'app/modules/account/account.module#AccountModule',
  },
  {
    path: 'event',
    loadChildren: 'app/modules/mobile-alarm/mobile-alarm.module#MobileAlarmModule' // 安全警報移動端處理
  },
  { path: 'error', loadChildren: 'app/modules/error/error.module#ErrorModule' }, // 錯誤
  { path: 'not-found', redirectTo: 'error/404' }, // 404 
  { path: '**', redirectTo: 'error/404' } // 錯誤 , 沒有匹配到任何路徑的都跳轉到404

];

// ModuleWithProviders 是個介面,就是允許ngModule和providers型別
export const AppRoutes: ModuleWithProviders = RouterModule.forRoot(routes, { useHash: true });


// 上面這種寫法只是把路由到處到一個變數,也就是要生效必須到相應的模組中引入(NgModule)中import進去複製程式碼

小技巧

  • 獲取url的id

  // 根據是否存在id判斷是新增還是修改
  checkAction() {
    // 用activatedRoute來獲取url上對應的引數
    this.activatedRoute.params.subscribe((params: { id: number }) => {
      if (params.id) {
        this.id = params.id;
      } else {
        this.showLoading = false;
      }
    });
  }


  // 這種是直接獲取queryParam
  this.activatedRoute.queryParams.subscribe(
      (res: { AlertType: string }) => {
        console.log(res);
      },
      (err):never => {
        console.log('我靠,網路錯誤');
      }
    );複製程式碼
  • 返回上個頁面
  // 取消
  back() {
    // 這裡判斷id,url進來的帶了一個關聯id,比如你要檢視一個使用者的詳細資訊,根據id關聯
    // 在這個頁面獲取到這個id,然後進行的路由的相對跳轉
    if (this.id) {
      this.router.navigate(['../../'], { relativeTo: this.activatedRoute });
    } else {
      this.router.navigate(['../'], { relativeTo: this.activatedRoute });
    }
  }複製程式碼

總結

基本專案用到一丟丟都榨乾出來了。。。
我知道我技術渣,若是有一些更好的技巧,一些更好的寫法。。亦或者是錯誤的
請留言,及時跟進,順便學習學習。。。

下一篇說點什麼好,,,自定義指令?自定義管道?待我捋一捋

相關文章