生成一个跟angular路由相关的项目:ng new router --routing;
生成组件:ng g component xx;
跟路由相关的五个对象:
五个对象在整个应用中的位置:
路由传递参数:
1:在查询参数中传递参数:
app.component.html:
第一种通过界面:<a [routerLink]="['/product']" [queryParams]="{id:1}">商品</a>
第二种通过typeScript:<button type="button" (click)="toProductDetails()">商品详情</button>
第二种:app.component.ts:
toProductDetails() {
this.router.navigate(['/product']);
}
product.component.ts:
// 快照的方式获取参数
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Params } from '@angular/router/src/shared';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private productId: number;
constructor(private routerInfo: ActivatedRoute) { }
ngOnInit() {
// 使用订阅方式 获取路由参数的时候,不确定是否从路由本身路由到本身,则使用订阅方式
this.routerInfo.params.subscribe((param: Params) => this.productId = param['id']);
}
}
2:在路由路径中传递参数:
app.component.html:
第一种通过界面: <a [routerLink]="['/product', 2]">商品</a>
第二种通过typeScript:<button type="button" (click)="toProductDetails()">商品详情</button>
第二种:app.component.ts:
toProductDetails() {
this.router.navigate(['/product', 3]);
}
// 在路由中配置
app-routing.module.ts:
{path: 'product/:id', component: ProductComponent}, // 带参数传递
product.component.ts:
// 从URL中获取参数
this.productId = this.routerInfo.snapshot.params['id'];
路由获取参数方式:
有快照和订阅两种方式,一般使用订阅
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Params } from '@angular/router/src/shared';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private productId: number;
constructor(private routerInfo: ActivatedRoute) { }
ngOnInit() {
// 快照的方式获取参数:
// this.productId = this.routerInfo.snapshot.queryParams['id'];
// this.productId = this.routerInfo.snapshot.params['id']; // 从URL中获取参数
// 使用订阅方式:
// 使用订阅方式 获取路由参数的时候,不确定是否从路由本身路由到本身,则使用订阅方式
this.routerInfo.params.subscribe((param: Params) => this.productId = param['id']);
}
}
路由配置:
重定向路由、找不到路径的默认路由
app-routing.module.ts:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } 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: '', redirectTo: '/home', pathMatch: 'full'},
{path: 'home', component: HomeComponent},
{path: 'product/:id', component: ProductComponent}, // 带参数传递
{path: 'home', component: HomeComponent},
// 找不到路径的默认路由
{path: '**', component: Code404Component}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
子路由:
在app-routing.module.ts中配置:
{path: 'product/:id', component: ProductComponent,
children: [
{path: '', component: ProductDetailComponent},
{path: 'seller/:id', component: SellInfoComponent}
]
},
在父界面product.component.html中的定义:
<!-- 这里注意:路径前面是有一个点的 . 表示在当前的路径下找其子路由 -->
<a [routerLink]="['./']">sell商品</a>
<a [routerLink]="['./seller', 66]">product详情商品</a>
<router-outlet></router-outlet>
辅助路由:
app.component.html:
<!-- 辅助路由 primary:'home',用来指定跳转到辅助路由的同时,跳转到主路由为home,可以不指定主路由primary-->
<a [routerLink]="[{outlets: {primary:'home' ,aux: 'chat'}}]">展示chat</a>
<a [routerLink]="[{outlets: {aux: null}}]">隐藏chat</a>
<router-outlet></router-outlet>
<!-- 在主路由router-outlet下添加一个带有name的 router-outlet-->
<router-outlet name="aux"></router-outlet>
app-routing.module.ts:
{path: 'chat', component: ChatComponent, outlet: 'aux'},
路由守卫:
CanActivate:处理导航到某路由的情况,满足某种情况才可以进入指定路由。
CanDeactivate:处理从当前路由离开的情况,只有满足某种情况,才能离开当前路由。
Resolve:在路由激活之前获取路由数据。
app-routing.module.ts:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ProductComponent } from './product/product.component';
import { Code404Component } from './code404/code404.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { SellInfoComponent } from './sell-info/sell-info.component';
import { ChatComponent } from './chat/chat.component';
import { LoginGuard } from './guard/login.guard';
import { UnsaveGuard } from './guard/unsave.guard';
import { ProductResolve } from './guard/product.resolve';
const routes: Routes = [
// 这里注意,path路径上不能有斜杠 /
{path: '', redirectTo: '/home', pathMatch: 'full'}, // 重定向路由
{path: 'home', component: HomeComponent},
{path: 'chat', component: ChatComponent, outlet: 'aux'},
{path: 'product/:id', component: ProductComponent,
children: [
{path: '', component: ProductDetailComponent},
{path: 'seller/:id', component: SellInfoComponent}
],
canActivate: [LoginGuard],
canDeactivate: [UnsaveGuard],
resolve: {
product: ProductResolve
}
},
{path: 'home', component: HomeComponent},
{path: '**', component: Code404Component}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [LoginGuard, UnsaveGuard, ProductResolve]
})
export class AppRoutingModule { }
-----------------------------------------------------------
login.guard.ts:canActivate
import { CanActivate } from '@angular/router';
export class LoginGuard implements CanActivate {
canActivate() {
const loggedIn: boolean = Math.random() < 0.5;
if (!loggedIn) {
console.log('用户未登录');
}
return loggedIn; // 返回true的时候
}
}
-----------------------------------------------------------
unsave.guard.ts:CanDeactivate
import { CanDeactivate } from '@angular/router/src/interfaces';
import { ProductComponent } from '../product/product.component';
// 针对要离开ProductComponent这个路由,则做处理
export class UnsaveGuard implements CanDeactivate< ProductComponent> {
canDeactivate(component: ProductComponent) {
return window.confirm('确定要离开么?');
}
}
-----------------------------------------------------------
product.resolve.ts:Resolve
import { Resolve } from '@angular/router/src/interfaces';
import { Product } from '../product/product.component';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Router } from '@angular/router';
import { Injectable } from '@angular/core';
@Injectable()
export class ProductResolve implements Resolve<Product> {
constructor(private router: Router) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const productId: string = route.params['id'];
if (productId === '2') {
return new Product(2, 'ssss');
}else {
this.router.navigate(['/home']);
}
}
}
-----------------------------------------------------------
product.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Params } from '@angular/router/src/shared';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private productId: number;
private productName: string;
constructor(private routerInfo: ActivatedRoute) { }
ngOnInit() {
// 使用另外一种获取参数的方式,data
this.routerInfo.data.subscribe((data: {product: Product}) => {
this.productId = data.product.id;
this.productName = data.product.name;
});
}
}
export class Product {
constructor(public id: number, public name: string) {}
}