12Angular路由

路由

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

<router-outlet></route-outlet>

注意:

  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}

  • 激活,并设置激活样式

<a [routerLink]="['/home',tab.link]" routerLinkActive="active-link">...</a>

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

  • 读取

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<Hero>
    constructor(private route: ActivatedRoute){} 
    ngOnInit(){
        this.hero$ = this.route.paramMap.pipe(
            switchMap(params =>{
            return this.service.getHero(params.get('id'))
        }))
    }
}
路径对象参数
  • 激活

<a [routerLink] = "['/home',tab.link,{name::'val1'}]">...</a>

编程式导航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}

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

<a [routerLink]="['/home']" [queryParams]={name:'val1'}>...</a>

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

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

  • 读取(区别于paramsMap)

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

嵌套路由

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

页面中可以有多个具名的router-outlet,但匿名的只能有一个
<a [routerLink]="['grand']" routerLinkActive="active" [queryParams]="{name:'zhangsan'}">
Link to grand</a>

<a [routerLink="[{outlets:{second:aux}}]"]>Link to Second</a>
<a [routerLink]="[{outlets:{popup:['second']}}]"></a>
<router-outlet></router-outlet>
<router-outlet name="second"></router-outlet>
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))
    ]
})
路由守卫
<a routerLink="./" [routerLinkActiveOptions]="{exact : true}"></a>
//相当于全部匹配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<boolean> | promise<boolean> | boolean;
}
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactive>{
    canDeactivate(component:CanComponentDeactivate){
        //return component.canDeactive ? component.canDeactive() : true;
        return component?.canDeactive()
    }
}
  • resolve守卫

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

  • CanLoad来处理异步导航到某特性模块的情况
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容

  • 一:路由基础 什么是路由: 在web开发中,路由的概念由来已久,简而言之,就是利用URL的唯一性来指定特定的事物,...
    真的稻城阅读 6,013评论 2 7
  • 一、SPA的概念 首先明确一个概念,SPA,全称为Single Page Application单页应用,一个单页...
    耦耦阅读 5,942评论 0 3
  • 一、创建一个带路由的项目 可以选择跳过安装。这里我遇到了npm 安装失败的情况。尝试了很多种方法。cnpm方式不要...
    LH_0811阅读 415评论 0 0
  • 一.课程简介 (注意:这里的AngularJS指的是2.0以下的版本) AngularJS的优点: 模板功能强大丰...
    壹点微尘阅读 913评论 0 0
  • 1. 路由是什么 路由(导航)本质上是切换视图的一种机制 2.路由的导航的URL是否真实存在 angular的路...
    程序猿吴阅读 200评论 0 0