ng4.x 路由配置及數據傳遞

路由:根據不同地址加載不同組件,實現單頁面應用


# 1 路由基礎知識 =================


在angular中主要提供了下面5個對象來處理應用中路由相關的功能:

Routes: ? ? ? ?路由配置,保存著哪個URL對應展示哪個組件,以及在哪個RouterOutlet中展示組件

RouterOutlet:在Html中標記路由內容呈現位置的占位符指令

Router: ? ? ? ? ?【控制器中】負責在運行時執行路由的對象,可以通過調用其navigate()和navigateByUrl()方法來導航到一個指定的路由

RouterLink: ? 【html模板中a】在Html中聲明路由導航用的指令

ActivatedRoute:當前激活的路由對象,保存著當前路由的信息,如路由地址,路由參數等 ? ? ? ? ? ? ? ? ? ? ?


ng new router --routing ? ? ? ? 創建路由項目

Q1:Routes

當我們使用routing參數生成項目時 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?在app目錄下會多生成一個app-routing.module.ts? 描述當前應用的路由配置 ? ? ? ? ? ?

主模塊app-module.ts中元數據imports中會導入新生成的AppRoutingModule

ng g component home ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

ng g component product ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

ng g component code404 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? 生成主頁 產品 404組件


路由配置:

《app-routing.module.ts》

import { NgModule } from '@angular/core'; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

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

?import {HomeComponent} from "./home/home.component"; ? ? ? ? ? ? ? ? ?

?import {ProductComponent} from "./product/product.component"; ? ? ? ?

import {Code404Component} from "./code404/code404.component";


const routes:Routes = [ ? ? ?//注:path不能用\開頭 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ?{path: '',component: HomeComponent}, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ??{path: 'product',component: ProductComponent},

? ??{path:'**',component:Code404Component} ? ??//放在路由配置的最后面 ?

];


@NgModule({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

imports: [ RouterModule.forRoot(appRoutes) ], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

exports: [ RouterModule ], ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?providers: [] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

})

export class AppRoutingModule { } ? ? ? //暴露模塊

《app.module.ts》:

import { AppRoutingModule } from './app-routing.module';

... ? ...

imports: [

? ? BrowserModule,

? ? AppRoutingModule ? ? ?//注冊路由模塊

]

Q2:RouterOutlet

當我們使用routing參數生成項目時 ?app.component.html中會生成插座指示當前導航到某個路由的時候對應組件顯示的位置[插座后面]

Q3:RouterLink

《app.component.html》

<a [routerLink]="['/]" ? routerLinkActive="active">主頁</a>

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

<router-outlet></router-outlet>


routerkinkactive:選中路由加載的class

.active{ ?color: red; } ? // 配置選中的樣式

說明:routerLink的參數是一個數組:有時需要在路由的時候傳遞一些參數,需要在數組中寫參數的值

Q4:Router ? ?-- js跳轉

《app.component.ts》:

import { Component } from '@angular/core'; ? ?

@Component({ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ?selector: 'app-root', ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? templateUrl: './app.component.html', ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ?styleUrls: ['./app.component.css'] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ?})

export class AppComponent { ? ?

? ? ? ? ? ?title = 'app';

? ? ? ?? constructor(private router:Router) { ? ?} ? ?

? ? ? ? ? ?toProductDetails() { ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?this.router.navigate(['/product']) ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? //? this.router.navigate(['/product' , 2]) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? }

Q5:ActivatedRoute


# 2 路由時傳遞數據 ===============


E1 : 在查詢參數中傳遞數據:

/product?id=1&name=2? ? =>? ActivatedRoute.queryParams[id]

E2 : 在路由路徑中傳遞數據:

{path:/product/:id}? ? =>? /product/1? ? =>? ActivatedRoute.params[id]

E3 : 在路由配置中傳遞數據:

{path:/product,component:ProductComponent, data[{isProd:true}]}? =>? ActivatedRoute.data[0][isProd]

導航到商品詳情頁的時候需要傳商品id給商品詳情組件:

E1:

《app.component.html》:【傳】

<a [routerLink] = "['/']">主頁</a>

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

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

? <router-outlet></router-outlet> ?

《product.component.ts》:【接】

import { Component ,OnInit} from '@angular/core';?

?import? {ActivatedRoute} from "@angular/router"; ? ?

? @Component({? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? selector: 'app-product', ? ? ? ?

? ? ? ? ? ? ? ? ? ? templateUrl: './product.component.html', ?

? ? ? ? ? ? ? ? ? ? ?styleUrls: ['./product.component.css'] ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? })

export class ProductComponent implements OnInit {

? ? ? ? private productId:number; ?

? ? ? ?constructor(private routeInfo: ActivateRoute) { } ? ?

? ? ? ?ngOnInit() { ? ? ? ? ? ? ?

? ? ? ? ? ? this.productId = this.routeInfo.snapshot.queryParams["id"]; ? ? ?

? ? ? ? ? ? } ?

?}

《product.component.html》:

<p>商品ID是:{{productId}}</p>

E2:

《app-routing.module.ts》

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

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

import {HomeComponent} from "./home/home.component";?

?import {ProductComponent} from "./product/product.component";?

?import {Code404Component} from "./code404/code404.component";

const routes:Routes = [ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? {path: '',component: HomeComponent}, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

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

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

?];

@NgModule({ ?imports: [ RouterModule.forRoot(appRoutes) ], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? exports: [ RouterModule ], ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? providers: [] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?})


export class AppRoutingModule { }

《app.component.html》:

<a [routerLink] = "['/']">主頁</a>?

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

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

?<router-outlet></router-outlet>

《product.component.ts》:

import { Component ,OnInit} from '@angular/core'; ?

import ?{ActivatedRoute} from "@angular/router"; ? ?

? @Component({ ? ?

? ? ? selector: 'app-product', ?

? ? ? ? templateUrl: './product.component.html', ? ?

? ? ? ? ?styleUrls: ['./product.component.css'] ? ? ?

? })

export class ProductComponent implements OnInit { ? ?

? ? ? ? ? private productId:number; ? ?

? ? ? ? constructor(private routeInfo: ActivateRoute) { } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ngOnInit() {? ?

? ? ? ? ? ? ?this.routeInfo.params.subscribe((params:Params) => this.productId = params ["id"]); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? }

從組件A 路由到組件B時,B組件會被創建,它的constructor方法會被調用,它的ngOnInit方法會被調用一次

但是如果從組件B到組件B ,ngOnInit方法不會再次創建,所以productId屬性保持著第一次創建時賦予的值

解決方案:?

** ? ?參數訂閱

this.routeInfo.params.subscribe((params:Params) => this.productId = params ["id"]):? ? ? ? ? ? ? ? ? ? ? + subscribe 訂閱

+ Params ?類型

+ 訂閱之后聲明一個匿名函數來處理傳進的參數params, 從參數中取出id賦給本地的productId

** ?參數快照:

ngOnInit() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? this.productId = this.routeInfo.snapshot.queryParams["id"]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}

小結:如果確定不會由組件A 路由到組件A 可使用參數快照,反之,使用參數訂閱

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容