Angular学习笔记02——路由

###1、路由基础

名称简介
Routes路由配置,保存着哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示组件。
RouterOutlet在Html中标记路由内容呈现位置的占位符指令。
Router负责在运行时执行路由的对象,可以通过调用其navigate()和navigateByUrl()方法来导航到一个指定的路由。
RouterLink在Html中声明路由导航用的指令。
ActivatedRoute当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等。

#####使用 1、创建带路由的angular项目
ng new router --routing项目名称为router,通过routing参数,使创建出来的项目带用路由的对应文件。
这样创建出的项目比不带routing多出app-routing.module.ts脚本文件,在该文件中可以定义Routes:

import { ProductComponent } from './product/product.component';//定义Routes,指定不同的path指向不同的组件
const routes: Routes = [{ path: '', component: HomeComponent },{ path: 'product', component: ProductComponent },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
复制代码

同时可以看到在app.component.html中:

主页
商品详情


复制代码

通过routerLink去引用前面定义的routes,实现页面的变换。变换的位置由html文件中的决定。

除了这种方法去调用路由之外,也可以通过脚本方法的方式去定义和调用路由,在app.component.ts文件中定义如下:

import { Router } from '@angular/router';@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']);}}
复制代码

配合html中按钮的点击事件,也可以实现路由的功能,使用的是router对象。 ###2、在路由时传递参数 a、在查询参数中传递 /product?id=1&name=2 => ActivatedRoute.queryParams[id]
代码示例:

主页
商品详情


复制代码

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;// 在构造函数里声明ActivatedRoute对象,在初始化方法里面通过ActivatedRoute对象获取查询参数constructor(private routerinfo: ActivatedRoute) {}ngOnInit() {this.productId = this.routerinfo.snapshot.queryParams['id'];}
}
复制代码

这里是商品信息组件!

商品ID:{{productId}}

复制代码

b、在路由路径中传递 {path:/product/:id} => /product/1 => ActivatedRoute.queryParams[id]
代码示例:

主页

商品详情


复制代码

import { ProductComponent } from './product/product.component';const routes: Routes = [{ path: '', component: HomeComponent },{ path: 'product/:id', component: ProductComponent },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
复制代码

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'];}}
复制代码

c、在路由配置中传递

{path:/product,component:ProductComponent,data:[{isProd:true}]}  =>  ActivatedRoute.data[0][isProd]
复制代码

代码示例如下:

主页


商品详情

	
复制代码

import { ProductComponent } from './product/product.component';const routes: Routes = [{ path: '', component: HomeComponent },// { path: 'product/:id', component: ProductComponent },{ path: 'product', component: ProductComponent, data: [{ id: 3 }] },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
复制代码

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((params: Params) => this.productId = params['id']);// this.productId = this.routerinfo.snapshot.queryParams['id'];// this.productId = this.routerinfo.snapshot.params['id'];this.productId = this.routerinfo.snapshot.data[0]['id'];}}
复制代码

####参数快照和参数订阅

  ngOnInit() {//订阅// this.routerinfo.params.subscribe((params: Params) => this.productId = params['id']);//快照// this.productId = this.routerinfo.snapshot.queryParams['id'];// this.productId = this.routerinfo.snapshot.params['id'];this.productId = this.routerinfo.snapshot.data[0]['id'];}
复制代码

###3、重定向路由 语法:{path:'xx',redirectTo: '/xxx', pathMatch: 'full' }
代码示例:

import { ProductComponent } from './product/product.component';const routes: Routes = [{ path: '', redirectTo: '/home', pathMatch: 'full' },{ path: 'home', component: HomeComponent },// { path: 'product/:id', component: ProductComponent },{ path: 'product', component: ProductComponent, data: [{ id: 3 }] },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})
export class AppRoutingModule { }
复制代码

###4、子路由 语法:

{path:'home',component:HomeComponentchildren:[{path:'',component:xxxComponent},{path:'/yyy',component:yyyComponent}]
}
复制代码

如果路由这样配置的话,访问路径是/home的时候,app的html中的标签会展示HomeComponent组件,HomeComponent组件的会展示xxxComponent组件。
当访问路径是/home/yyy的时候,app的html中的标签会展示HomeComponent组件,HomeComponent组件的会展示yyyC omponent组件。 ###5、辅助路由 语法:


{path:'xxx',component:xxxComponent.outlet:'other'}
{path:'yyy',component:yyyComponent.outlet:'other'}xxx
yyy
复制代码

也可以通过下面的方法调用来实现主路由同时变化,让主路由跳转到home路径:

yyy
复制代码

###6、路由守卫 对路由的访问进行控制,增加额外的业务逻辑判断功能。可以用于如下场景:
1、只有当用户已经登录并拥有某些权限时才能进入某些路由。
2、一个多个表单组成的向导,如注册流程,用户只有在当前路由的组件中完成了满足条件的信息才可以导航到下个路由。
3、当用户未执行保存操作而试图离开当前导航时提醒用户。
代码实现如下:

import { ChildrenOutletContexts } from '@angular/router/src/router_outlet_context';
import { OutGuard } from './guard/out.guard';const routes: Routes = [{ path: '', redirectTo: '/home', pathMatch: 'full' },{ path: 'chat', component: ChatComponent, outlet: 'aux' },{ path: 'home', component: HomeComponent },{path: 'product/:id', component: ProductComponent,children: [{ path: '', component: ProductDescComponent },{ path: 'sellerInfo/:id', component: SellerInfoComponent }], //在路由配置中增加如下配置,类似于方法拦截器,canActivate是进入当前组件需要执行的守卫,canDeactivate是离开当前组件需要执行的方法。canActivate: [LoginGuard], canDeactivate: [OutGuard]},// { path: 'product', component: ProductComponent, data: [{ id: 3 }] },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],//守卫类需要在这里进行注册providers: [LoginGuard, OutGuard]
})
export class AppRoutingModule { }
复制代码

守卫类的实现:
import { CanActivate } from '@angular/router'; //需要实现接口并实现接口定义的方法 export class LoginGuard implements CanActivate { canActivate() {

        // tslint:disable-next-line:prefer-constlet loginIn: boolean = Math.random() < 0.5;if (!loginIn) {console.log('用户未登录!');}return loginIn;}}
复制代码

import { ProductComponent } from './../product/product.component';
import { CanDeactivate } from '@angular/router';export class OutGuard implements CanDeactivate {canDeactivate(component: ProductComponent) {return window.confirm('是否确定离开本页面?');}}
复制代码

###7、resolve守卫 作用:在路由跳转之前提前加载数据或其他操作,提高用户体验。
代码实现:

import { OutGuard } from './guard/out.guard';const routes: Routes = [{ path: '', redirectTo: '/home', pathMatch: 'full' },{ path: 'chat', component: ChatComponent, outlet: 'aux' },{ path: 'home', component: HomeComponent },{path: 'product/:id', component: ProductComponent,children: [{ path: '', component: ProductDescComponent },{ path: 'sellerInfo/:id', component: SellerInfoComponent }],// canActivate: [LoginGuard],// canDeactivate: [OutGuard]//配置resolve,声明需要传到下一个组件的参数resolve: {product: ProductResolve}},// { path: 'product', component: ProductComponent, data: [{ id: 3 }] },{ path: '**', component: Code404Component }
];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],//注册providers: [LoginGuard, OutGuard, ProductResolve]
})
export class AppRoutingModule { }
复制代码

import { Product } from '../product/product.component';@Injectable()//需要注册当前类,实现内部依赖注入Router对象
export class ProductResolve implements Resolve {constructor(private router: Router) { }resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Product | Observable | Promise {// tslint:disable-next-line:prefer-constlet productId: number = route.params['id'];// tslint:disable-next-line:triple-equalsif (productId == 1) {return new Product(1, '商品1');} else {this.router.navigate(['/home']);}}}
复制代码

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() {// this.routerinfo.params.subscribe((params: Params) => this.productId = params['id']);// this.productId = this.routerinfo.snapshot.queryParams['id'];// this.productId = this.routerinfo.snapshot.params['id'];// this.productId = this.routerinfo.snapshot.data[0]['id'];//获取具体参数this.routerinfo.data.subscribe((data: { product: Product }) => {this.productId = data.product.id;this.productName = data.product.name;});}}
//实现product实体类
export class Product {constructor(public id: number, public name: String) { }
}
复制代码

转载于:https://juejin.im/post/5a2def1651882560e3569480


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部