1. 程式人生 > >Angular 路由配置詳解

Angular 路由配置詳解

今天剛剛看完Angular的路由配置,總結出來供小夥伴分享,也是為了自己以後檢視!!!(環境為:win、WebStorm)
先建立一個帶路由的Angular專案router:

ng new router --routing

這裡有一個小坑,有可能你建立的專案目錄回缺少:node_modules資料夾
新增node_modules資料夾的方法為:進入router輸入一下程式碼

 npm install

隨便在這裡把生成新的元件的程式碼貼上去:

ng g component home

1、路由5個引數

  • Routers :路由配置,儲存著哪個URL對應展示哪個元件,以及在哪個RouterOutlet中展示元件的引數。常用引數為:path、component:;
  • RouterOutlet :在Html中標記路由指向的元件出現的位置,出現在該引數的後面
  • Router:負責在執行時執行路由的物件,可以通過呼叫navigate()和navigateByUrl()方法來導航到一個指定的路由上去。
  • RouterLink:在Html中宣告路由導航的指令
  • ActivatedRoute:當前啟用的路由物件,儲存著當前路由的資訊,如路由地址、路由引數等。

2、配置簡單的路由和萬用字元路由

建立兩個元件:home 、product;
第一步:Routers的配置:

 {path: 'home', component: HomeComponent},
 {path
: 'product', component: ProductComponent
},

path:設定URL
component:設定ULR指向一個元件
注:元件需要匯入:

import {HomeComponent } from './home/home.component';
import {ProductComponent} from './product/product.component';

win下的快捷鍵為:Alt+Enter;
第二步:在app.component.html中設定程式碼

<a [routerLink]="['/home']">主頁</a
>
<a [routerLink]="['product']">商品詳情</a> <router-outlet></router-outlet>

routerLink:指向的URL
router-outlet:標記routerLink指向的URL的元件出現的位置,元件在其之後出現

這樣一個簡單的路由就配置好了。可以實現單頁應用。

一些更加複雜東西
用button來實現上面a連結的作用:

<input type="button" value="商品詳情" (click)="toProductDetails()">

當點選button觸發點選事件。點選事件使用Router.navigate()函式進行導航

toProductDetails() {
    this.router.navigate(['/product']);
  }

要使用Router.navigate()函式前要宣告一個Router的變數,並且import :Router:

constructor(private router: Router) {}

當時輸入一個錯誤的URL時,應該設定一個萬用字元路由來導航到一個指定的元件上:

{path: '**', component: Code404Component}

**表示任何URL都可以導航到該URL指向的元件上(必須放在使用路由的最後面)

3、在路由時傳遞資料(三種方式)

  • 在查詢引數中傳遞: /product?id=1 => ActivatedRouter.queryParams[id]
  • 在路由路徑中傳遞: {path:/product/:id} => /product/1 => ActivatedRouter.params[id]
  • 在路由配置中傳遞:{path:/product, component:ProductComponent, data:[{isProd:true}]} => ActivatedPouter.data[0][isProd]

    在查詢引數中傳遞(2步)
    修改RouterLink:

<a [routerLink]="['product']" [queryParams]="{id:1}">商品詳情</a>

在product.componet.ts檔案中接收這個引數:

 public productId: number;
 constructor(private routerInfo: ActivatedRoute) { }
 ngOnInit() {
    this.productId = this.routerInfo.snapshot.queryParams['id'];
  }

在路由路徑中傳遞(三步)
修改路由配置Routers:

  {path: 'product/:id', component: ProductComponent},

修改RouterLink:

<a [routerLink]="['product',1]">商品詳情</a>

接收引數:

 public productId: number;
  constructor(private routerInfo: ActivatedRoute) { }
  ngOnInit() {
    this.productId = this.routerInfo.snapshot.params['id'];
  }

4、引數快照、引數訂閱

遇到的問題:當我進入一個元件a並且傳入了一個引數b,這時候頁面是沒有任何問題的,但是當我再次從元件a進入元件a並且傳入了一個相同name的引數b時,b的值不會改變。那我如何在這個情況下讓b的值改變喃???
使用引數訂閱功能就ok了;
其他程式碼不變,改變接收引數的程式碼:

this.routerInfo.params.subscribe((params: Params) => this.productId = params['id']);

5、重定向路由

重定向路由顧名思義:就是訪問某個路由時,重定向到一個指定的路由上去:

{path: '', redirectTo: '/home', pathMatch: 'full' },

當訪問 空路由時,重定向到 home路由上去

6、子路由

在路由中設定路由(children):

 {path: 'product', component: ProductComponent,
    children: [
      {path: '', component: ProductDescComponent},
      {path: 'sellerinfo', component: SellerinfoComponent},
    ],
  },

在RouterLink中要加上:“./”:

<a [routerLink]="['./sellerinfo']">銷售人員id</a>

7、輔助路由(3步)

輔助路由的作用:無論路由如何導航,頁面如何跳轉,輔助路由導航的元件始終在頁面上不會消失;如同一個網站需要聊天元件,而已要求聊天元件始終在頁面上顯示時,就需要使用輔助路由。

  • 設定插座-RouterOutlet
  • 配置路由-Routers
  • 設定導航

    設定插座需要給Routeroutlet設定一個name:

<router-outlet name="aux"></router-outlet>

配置路由-Routers,將Routeroutlet的name給outlet:

{path: 'sellerinfo', component: SellerinfoComponent, outlet: 'aux'},

設定導航:

<a [routerLink]="[{outlets: {aux: 'chat'}}]">開始聊天</a>
<a [routerLink]="[{outlets: {aux: null}}]">結束聊天</a>

null表示:不顯示元件(如果已經顯示了元件就隱藏)

特殊的導航設定(當點選該a連結時,不僅僅顯示輔助路由導航的元件,還會顯示home元件):

<a [routerLink]="[{outlets: {primary:'home', aux:'chat'}}]">開始聊天並且跳轉到home</a>

7、路由守衛(三種守衛)

保證滿足某個條件和許可權,才能離開或者進入某個路由導航的元件時,使用路由守衛。

  • CanActivate:處理導航到某路由的情況
  • CanDeactive:處理從當前路由離開的情況
  • Resolve:在路由啟用之前獲取路由資料

    CanActivate的設定(兩步):
    1、建立一個*.ts的檔案來實現CanActivate
    如:建立檔案:login-guard
    實現CanActivate:

import {CanActivate} from '@angular/router';
export class LoginGuard implements CanActivate {
  canActivate() {}
    return boolean;
  }
}

boolean 為true時,進入路由
反之不能進入路由

2、設定路由配置:

{path: 'product/:id', component: ProductComponent,
canActivate:[LoginGuard]},

同要設定依賴注入:

@NgModule({
  providers: [LoginGuard]
})

CanDeactive設定(兩步):
1、建立一個*.ts的檔案來實現CanDeative
如:建立檔案:unsaved-guard
實現CanDeative:

import {CanDeactivate} from '@angular/router';
import {ProductComponent} from '../product/product.component';

export class UnsavedGuard implements CanDeactivate<ProductComponent> {
   canDeactivate(component: ProductComponent) {}
}

ProductComponent 是要守衛的路由
2、設定路由配置:

{path: 'product/:id', component: ProductComponent,
canDeative:[UnsavedGuard]},

同要設定依賴注入:

@NgModule({
  providers: [UnsavedGuard]
})

Resolve設定(三步):
1、建立一個*.ts的檔案來實現Resolve
如:建立檔案:product-resolve.ts
實現Resolve:

import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router';
import {Product} from '../product/product.component';
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';

@Injectable()
export class ProductResolve implements Resolve<Product> {
  constructor(private router: Router) {}
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product> | Promise<Product> | Product {
    const productId: number = route.params['id'];
    if (productId == 1) {
      return new Product(1, 'iPhone7');
    }else {
      this.router.navigate(['/home']);
    }
    return undefined;
  }
}

Product是類要去,應該在所要守衛的路由元件上去實現一個類:

export class Product {
  constructor (public id: number, public name: string) {}
}```

2、設定路由配置:

{path: ‘product/:id’, component: ProductComponent,
resolve: {
product: ProductResolve
}
},

同要設定依賴注入:

@NgModule({
providers: [ProductResolve]
})

3、設定引數接收Resolve傳入的引數:

export class ProductComponent implements OnInit {
public productId: number;
public productName: string;
constructor(private routerInfo: ActivatedRoute) { }

ngOnInit() {
this.routerInfo.data.subscribe((data: {product: Product}) => {
this.productId = data.product.id;
this.productName = data.product.name;
});
}

}
“`