今天刚刚看完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;
});
}
}
“`