12Angular路由

路由

Angular是单页程序,路由显示的路径不过是一种保存路由状态的机制,这个路径在web服务器中不存在


注意:

  1. 插入的视图位于router-outlet的下方,而非内部
  2. 页面中可以有多个具名的router-outlet(辅助插座),但匿名的只能有一个
  3. 使用得插座过多,反而会导致一些副作用,使路由难以理解。通常情况下,都可以使用子、孙路由的嵌套来解决。
npm i -g http-serve
ng build --prod//编译
http-server . //监听当前目录8080端口

此时强制刷新,找不到页面,返回404,通常需要重定向到index页

ng g c not-found --skipTests -c OnPush -s

创建路由模块

ng g m list --routing

路由定义

const routes:Routes = [
    {
        path:'',
        redirectTo:'home',
        pathMatch:'full'
    },
    {
        path:'home',
        component:HomeContainerComponent,
        children:[
            {
                path:'',
                redirectTo:'hot',
                pathMatch:'full',
            },
            {
                path:':tabLink',
                component:HomeDetailComponent
            } 
        ]
    },
    {
    //前面的都没有符合,通过通配符匹配到最后的404
        path:'**',
        component:NotFoundComponent
    }
]

需要动态传输路由表时,在path的值前面加一个“:”

导入RouterModule

根模块forRoot 子模块forChild

@NgModule({
    imports:[RouterModule.forRoot(routes,{enableTracing:true})],
    export:[RouterModule]
})

enableTracing可以跟踪url的变化,当导航发生变化时,会打印一堆日志。

为时刻监听路由的变化,

注意模块导入的顺序,AppRoutingModule是最后一个,否则会被其他的拦截。

路径参数

  • 配置

{path:':tabLink',component:HomeDetailComponent}

  • 激活,并设置激活样式

...

编程式导航this.router.navigate(['home',tab.link]);

  • URL
    http://localhost:4200/home/sports
  • 读取

this.route.paramsMap.subscribe(params => {...});

路由传参

this.router.navigateByUrl('/hero/' + id)
this.router.navigate(['/hero/', id])

const routes: Routes = [
    {
        path:'hero/:id',
        component:HeroDetailComponent
    }
]

子模块读取

export class HeroDetailComponent implements OnInit {
    hero$: Observalbe
    constructor(private route: ActivatedRoute){} 
    ngOnInit(){
        this.hero$ = this.route.paramMap.pipe(
            switchMap(params =>{
            return this.service.getHero(params.get('id'))
        }))
    }
}
路径对象参数
  • 激活

...

编程式导航this.router.navigate(['home',tab.link,{name:'val1'}]);

  • URL

http://localhost:4200/home/sports;name=val1

  • 读取
    this.route.paramsMap.subscribe(params => {...});
  • snapshot (当不需要Observable时的替代品)
this.selectedId = this.route.snapshot.paramMap.get('id')
查询参数(路径中?后的字典值,可以和路径参数并存)
  • 配置

{path:'home',component:HomeContainerComponent}

  • 激活(路径参数+查询参数)

...

  • this.router.navigate(['home'],{queryParams:{name:'val1'}})
  • URL

http://localhost:4200/home?name=val1

  • 读取(区别于paramsMap)

this.route.queryParamsMap.subscribe(params => {...})

嵌套路由

通常一级路由是绝对路径,二级路由以下设置为相对路径

页面中可以有多个具名的router-outlet,但匿名的只能有一个

Link to grand

Link to Second



const namedRoutes:Routes = [
    {
        path:'compose',
        component:ComposeMessageCompoent,
        outlet:'second'
    }
]
const routes:Routes = [
    {path:'',redirectTo:'/heroes',pathMatch:'full'},
    {path:'**',component:NotFoundComponent}
]
@NgModule({
    imports:[
        RouterModule.forRoot(routes.concat(namedRoutes))
    ]
})
路由守卫

//相当于全部匹配patchMatcher:'full'
  • CanActivate导航到某路由
ng g g router-study/auth

阻止进入到admin路由

const routes:Routes = [
    {
        path:'admin',
        component:AdminComponent,
        canActivate:[AuthGuard],
        children:[
            {
                path:'',
                children:[
                    {path:'crises',component:CrisesComponent},
                    {path:'heroes',component:HeroesComponent},
                    {path:'',component:DashboardComponent}
                ]
            }
        ]
    }
]

export class AuthGuard implements CanActivate{
    canActive(
        next:ActivatedRouteSnapshot,
        state:RouterStateSnapshot
    ):boolean {
        return true;
        //只有返回值为true时,路由才放行
    }
}
  • CanActivateChild导航到某子路由

阻止进入到children

const routes:Routes = [
    {
        path:'admin',
        component:AdminComponent,
        children:[
            {
                path:'',
                canActivate:[AuthGuard],
                children:[
                    {path:'crises',component:CrisesComponent},
                    {path:'heroes',component:HeroesComponent},
                    {path:'',component:DashboardComponent}
                ]
            }
        ]
    }
]
  • CanDeactivate从当前路由离开

返回true可以离开

export interface CanComponentDeactivate {
    canDeactivate:()=> Observale | promise | boolean;
}
export class CanDeactivateGuard implements CanDeactivate{
    canDeactivate(component:CanComponentDeactivate){
        //return component.canDeactive ? component.canDeactive() : true;
        return component?.canDeactive()
    }
}
  • resolve守卫

保证了数据获取后再进行路由跳转,防止因数据延迟而出现的空组件情况,以此增强用户体验。

  • CanLoad来处理异步导航到某特性模块的情况

你可能感兴趣的:(12Angular路由)