子路由
- 新建两个组件,商品描述组件和销售员信息,进入商品详情页面会默认展示商品描述
{path:'product',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:sellerInfo},
]},
<a [routerLink]="['./']">商品描述</a>
<a [routerLink]="['./seller',99]">销售员信息</a>
<router-outlet></router-outlet>
- 获取商品的id
export class SellerInfoComponent implements OnInit{
private sellerId:number;
constructor(private routeInfo:ActivatedRoute){}
ngOnInit(){
this.sellerId=this.routeInfo.snapshot.params["id"];
}
}
辅助路由
- 这个路由的存在和消失并不是由主路由来控制的,而是单独控制的,主路由之间相互切换,它都会一直存在/消失
- 在任何页面中都有一个聊天控件随时可以聊天,在App组件的模板上在定义一个插座(<router-outlet>)来显示聊天面板,单独开发一个聊天组件,只显示新定义的插座上,通过路由参数 控制新插座是否显示聊天面板
(设置聊天组件的样式大小为30%,其他所有组件使用div包裹占据70%)
- 在app模板中使用router-outlet的name指向一个aux,在定义路由的路径是会多出一个属性outlet,使它的值和router-outlet的name的值相同
<router-outlet></router-outlet>
<router-outlet name="aux"></router-outlet>
{path:'chat',component:ChatComponent,outlet:'aux'},
- 设置这个聊天组件是否显示
<a [routerLink]="[{outlets:{aux:'chat'}}]">开始聊天</a>
<a [routerLink]="[{outlets:{aux:null}}]">结束聊天</a>
- 点击开始聊天的时候,在显示聊天组件的同时也会跳转到home路由
<a [routerLink]="[{outlets:{primary:'home',aux:'chat'}}]">开始聊天</a>
路由守卫
- 当用户满足某些条件是才会被允许进入某些路由,例如只有当用户已经登录时并拥有某些权限才能进入某些路由,一个由多个表单组件组成的向导,例如注册的流程,用户只有在满足当前路由要求填写的信息才能进入下一步导航到下一个路由,当用户未执行保存操作而试图离开时提醒用户
- CanActivate:处理导航到某路由的情况(当不能满足这个守卫的要求,就不能导航到指定的路由)
- CanDeactivate:处理从当前路由离开的情况(当不能满足这个守卫的要求,就不能从当前路由离开)
- Resole:在路由激活之前获取路由数据
- 在app文件夹下新建一个guard文件夹新建一个login.guary.ts文件(随机生成0-1的数模拟用户登录,如果大于0.5则是未登陆)
import {CanActivate} from "@angular/router"
export class LoginGuard implements CanActivate{
CanActivate() {
let loggedIn:boolean=Math.random() < 0.5;
if(!loggedIn){
console.log("用户未登陆");
}
return undefined;
}
}
- 在路由模板中判断如果有一个为false就会被拒绝访问,并且在模块中再声明一次LoginGuard
{path:'product',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:sellerInfo}
],CanActivate:[LoginGuard],
},
@NgModule({
providers:[LoginGuard]
})
- 新建一个unsave.guary.ts文件,当用户试图离开产品信息组件时
import {CanDeactivate} from "@angular/router"
import {ProductComponent} from "../product/product.component"
export class UnsaveGuard implements CanDeactivate<ProductComponent>{
CanDeactivate() {
return window.confirm("未保存")
}
}
{path:'product',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:sellerInfo}
],CanActivate:[LoginGuard],
CanDeactivate:[UnsaveGuard]
},
providers:[LoginGuard,UnsaveGuard]
- 新建一个product.resolve.ts,获取商品的id,如果id不为1 则会 返回到home
import {Resolve,ActivatedRouteSnapshot,RouterStateSnapshot,Router} from "@angular/router"
import {ProductComponent} from "../product/product.component";
import {Observable} from "rxjs";
import {Injectable} from "@angular/core"
@Injectable()
export class ProductResolve implements Resolve<Product>{
constructor(private router:Router){}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): <Product> | Promise<Product> | Product {
let id:number=route.params["id"];
if(productId==1){
return new Product(1,"niz")
}else{
this.router.navigate(['/home'])
}
return undefined;
}
}
- 在商品信息模块中有一个product对象
export class Product {
constructor(public id:number,public name:string)
}
- 将守卫加入到路由中,并同样在providers中声明,在商品模块中声明并且获取商品name与之前声明的id一致
{path:'product',component:ProductComponent,children:[
{path:'',component:ProductDescComponent},
{path:'seller/:id',component:sellerInfo}
],resolve:{
product:ProductResolve
}
},