Angular 2 路由
Angular 2 路由
angular2路由是管理angular2應用內部導航的一個重要內容,在angular應用中,很多的元件是通過組合完成一個複雜的應用,不可避免的是我們常會在檢視間切換,那麼這是就需要使用路由來管理檢視間的轉換。
路由定義
先看一個簡單的路由定義
///<reference path="../node_modules/angular2/typings/browser.d.ts"/>
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'
import {parentCmp} from "./parent.component";
import {planetList} from "./planet-list.component";
@Component({
selector: 'my-app',
template: `
<h3 class="title">Angular 2 Router Example</h3>
<nav>
<a [routerLink]="['Parent']">parent</a>
<a [routerLink]="['PlanetList']">planetList</a>
</nav>
<router-outlet></router-outlet>
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{
path: '/contact',
name: 'Parent',
component: parentCmp,
useAsDefault: true
},
{
path: '/planetList',
name: 'PlanetList'
component: planetList
}
])
export class RouteExampleAppComponent { }
從這個例子可以看出路由定義的過程
1、 引入路由元件import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router'
2、 引入我們所需的導航元件
import {parentCmp} from "./parent.component";
import {planetList} from "./planet-list.component";
3、 定義元件,配置模板,定義路由
<a [routerLink]="['Parent']">parent</a>定義了一個路由,其中的Parent是我們的一個的一個路由標籤,來自下面的路由配置,注意使用駝峰的表達方式。
<router-outlet></router-outlet>定義了檢視的顯示位置,即導航的模組顯示區域
directives: [ROUTER_DIRECTIVES],引入路由指令
@RouteConfig:用於進行路由配置,其中path只路由的路徑,在url中能夠看到;name指路由的名稱,和上面導航一致;component路由的元件即路由指向的元件。
這樣一個簡單的路由元件就基本完成
路由使用
import {bootstrap} from 'angular2/platform/browser';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {RouteExampleAppComponent} from "./myRoute";
bootstrap(RouteExampleAppComponent, [ROUTER_PROVIDERS]);
這裡和前面的bootstrap元件呼叫不同的是除了引入自定義的元件外還需要注入angular的路由服務。
父子路由
在我們的實際應用中還常遇到這樣的一個場景,父元件中包含了一些路由配置,在子元件中同樣還有路由配
置,有些情況下還需要在父元件通過路由傳遞資料到子元件中,那麼這些情況如何實現呢?
看一個例子
myRoute.ts
///<reference path="../node_modules/angular2/typings/browser.d.ts"/>
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {home} from "./home";
import {childRoute1} from "./childRoute1";
import {childRoute1Detail} from './ChildRoute1Detail'
@Component({
selector: 'my-app',
template: `
<h3 class="title">Angular 2 Router Example</h3>
<nav>
<a [routerLink]="['Home']">Home</a>
<a [routerLink]="['ChildRoute1']">子路由</a>
</nav>
<router-outlet></router-outlet>
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
name: 'ChildRoute1',
component: childRoute1
},
{
path: '/childRoute1Detail',
name: 'ChildRoute1Detail',
component: childRoute1Detail
}
])
export class RouteExampleAppComponent { }
這是一個父元件,裡面加入了路由配置,其中ChildRoute1是一個子路由,而'ChildRoute1Detail'是一個子路
{
path: '/',
name: 'Home',
component: home,
useAsDefault: true
},
{
path: '/childRoute1',
由的子路由即孫子路由,這些路由都在父元件中進行了設定。
childRoute.ts
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {Router, RouteParams} from 'angular2/router';
import {childRoute1Detail} from './ChildRoute1Detail'
@Component({
selector: "childRoute1",
template: ` this is a route
<a (click)="onSelect()">點選</a>
<a [routerLink]="['ChildRoute1Detail']">子路由明細1</a>
directives: [ROUTER_DIRECTIVES]
})
export class childRoute1 {
constructor(private _router: Router, private _routeParams: RouteParams) {
}
onSelect() {
this._router.navigate(['ChildRoute1Detail']);
}
};
directives: [ROUTER_DIRECTIVES]
})
export class childRoute1 {
constructor(private _router: Router, private _routeParams: RouteParams) {
}
onSelect() {
this._router.navigate(['ChildRoute1Detail']);
}
};
這是一個子元件,裡面沒有路由配置,使用的是父元件中的路由配置,這裡的兩個連結實現的功能是一樣的,都是將孫子元件載入到父元件的router-outlet中。
childRoute1Detail.ts
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: "childRoute1Detail",
template: `<h1>子路由1明細</h1>`
})
export class childRoute1Detail { };
這是一種應用場景,但這種應用場景顯然不是好的選擇,因為實際開發中各個模組可能都是單獨開發,父元件也可能不知道究竟會有多少個子元件路由,子元件路由交給子元件來配置可能是最好的方式了,那麼如何實現呢?
我們需要將父元件myRoute中的不屬於它的路由'ChildRoute1Detail'移除,並放在子元件childRoute中,注意父元件不能和子元件有相同的路由配置,否則會出現下面的錯誤。
在子元件childRoute加入'ChildRoute1Detail'路由時還需要使用useAsDefault: true配置
@RouteConfig([
{
path: '/childRoute1Detail',
name: 'ChildRoute1Detail',
component: childRoute1Detail,
useAsDefault: true
}
])
否則會出現
同時在父元件的路由路徑中需要對子路由加入“…”來標識這是個子路由,否則會出現下面錯誤
@RouteConfig([
{
path: '/',
name: 'Home',
component: home,
useAsDefault: true
},
{
path: '/childRoute1/...',
name: 'ChildRoute1',
component: childRoute1
}
])
完整的childRoute1.ts
import {childRoute1Detail} from './ChildRoute1Detail'
@Component({
selector: "childRoute1",
template: `
this is a route
<a (click)="onSelect()">點選</a>
<a [routerLink]="['ChildRoute1Detail']">子路由明細1</a>
<router-outlet></router-outlet>
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{
path: '/childRoute1Detail',
name: 'ChildRoute1Detail',
component: childRoute1Detail,
useAsDefault: true
}
])
export class childRoute1 {
constructor(private _router: Router, private _routeParams: RouteParams) {
}
onSelect() {
this._router.navigate(['ChildRoute1Detail']);
}
};
路由引數
通過在routelink或route.navigate中可以指定引數,如下
<a [routerLink]="['ChildRoute1Detail', {param1: param1}]">子路由明細1</a>
this._router.navigate(['ChildRoute1Detail', {param1:this.param1}]);
這是兩種方式傳遞param1引數
接受路由引數使用RouteParams或RouteData
this.param1 = routeParams.get("param1");
使用routedata方式則需要在路由配置中加入data標籤,如下
@RouteConfig([
{
path: '/childRoute1Detail',
name: 'ChildRoute1Detail',
component: childRoute1Detail,
data: { param1:"routedata " },
useAsDefault: true
}
])
使用時
constructor(data: RouteData) {
this.param1 = data.get("param1");
}
這裡要注意的是路由引數通常情況下我們不建議傳遞複雜型別的引數,我們可以傳遞id引數,然後在通過一個service注入並通過這個id找出該複雜型別的例項。
另外,在使用路由引數時不能忘記引用
import {Router, RouteParams} from 'angular2/router';
或
import { RouteData} from 'angular2/router';