Angular路由

作者: 咖啡浮点 | 来源:发表于2018-02-22 21:43 被阅读0次

    第二节:路由介绍

    1.生成新项目

    ng new 项目名 --routing : 注意 --routing的作用 .主模块、根组件引入route模块、组件。

    2.Angular Route导航的四大对象:

    Routes、RouteOutlet、Router、RouterLink、ActivatedRoute


    routerProperty.png
    • Routes: 进行路由的配置,使路由地址与组件相对应,并指定路由在哪个RouteOutlet中配置
    • RouteOutlet:路由对应组件的展示位置
    • Router: 在ts 文件进行路由的导航
    • RouterLink: 在HTML文件进行路由的导航
    • ActivatedRoute: 记录当前激活路由的对象,保存其信息,包括地址、组件、参数等。

    3.app-routing.module.ts 配置Routes

     const routes: Routes = [
         {
             path: '',
             component: HomeComponent  //Mac上通过option + enter 引入相应组件
         },
         {
             path: 'stock',
             component: StockComponent
         },
         {
             path: '**',
             component: Code404Component
         }
     ];
    

    注意:path属性不需要加‘/’。通配符配置,放在最后面,否则它后面的路由不会被加载,作用: 匹配找不到的其他路由。

    并引入对应的组件:

        import {StockComponent} from "./stock/stock.component";
        import {HomeComponent} from "./home/home.component";
        import {Code404Component} from "./code404/code404.component";
    

    4.routerLink的应用:

    在app.component.html文件中:
    <a [routerLink]="['/']">主页</a>
    <a [routerLink]="['/stock']">股票</a>
    注意: 只在HTML页面设置跳转链接,可以完成跳转
    

    5.router的应用:

      (1).app.component.html文件中:
      <button (click)="toStockDatail()">股票详情</button>
      
      (2).app.component.ts文件中:
      import {Router}  from "@angular/router";
      export class AppComponent {
          constructor(private router: Router) {  // 通过constructor引入Router
          }
          toStockDatail() {
              this.router.navigate(['/stock']);  // 导航到指定路由
          }
      }
    

    注意:所有的组件都会在<router-outlet></router-outlet>后面展示
    路由跳转后相应组件是加载在插座RouteOutlet的后面

    6.针对不存在的路由的设置

    通配符配置:app-routing.module.ts

    ...
    {
               path: '**',
               component: Code404Component
    }
    ...
    

    注意: 通配符配置应放在路由配置的最后面,否则不会跳转其它的路由。

    第三节 在路由中传递参数

    1.链接中的查询参数中传递数据

    app.component.html
    <a [routerLink]="['/stock']" [queryParams]="{id: 1}">股票</a>
    
    此时的路由为: localhost:4200/stock?id=1    
    接收数据:
    stock.component.ts
    (1)引入ActivatedRoute
    import {ActivatedRoute} from "@angular/router";
    constructor(private  routeInfo: ActivatedRoute) {}
    (2)定义数据:
    private stockId: number;
    (3)接收数据:
    this.stockId = this.routeInfo.snapshot.queryParams['id'];
    
    展示数据:
    stock.component.html
    {{stockId}}
    

    2.在URL中传递

    (1)修改路由定义:  
    
    app-routing.module.ts
        {path: 'stock/:id',component: StockComponent}
        (2)修改路由链接: app.component.html
        <a [routerLink]="['/stock',1]">股票</a>
        (3)接收参数: stock.component.ts
        this.stockId = this.routeInfo.snapshot.params['id'];
    

    3.在ts文件中传递数据:

        app.component.ts
        toStockDatail() {
            this.router.navigate(['/stock', 2]);
        }
    

    注意: 接收参数方式与第二种一致

    问题: 通过不同方式跳转到相同组件时,传递不同的数据,数据并不会被渲染。
    所以:this.stockId = this.routeInfo.snapshot.params['id'];这个方式是由局限性的。只在第一次加载组件时,读取参数。
    
    解决办法: 新的传递方式:参数快照  参数订阅
    this.routeInfo.params.subscribe((params: Params) => this.stockId = params["id"]);
    

    4.在路由配置中传递数据,而非在路径中传递静态数据:

    (1)传递数据  
    {path: 'stock/:id',component: StockComponent,data: [{isPro: true}] }
    
    (2)接收数据:
    stock.component.ts:
     private  isPro:boolean;
     this.isPro = this.routeInfo.snapshot.data[0]['isPro'];
    

    第四节 路由的重定向

    { path: '', redirectTo: '/home', pathMatch: 'full' }
    其中pathMatch: 'full' 是指当且仅当路由是''时,才会精准跳转到'/home'。

    第五节 路由的嵌套: 子路由

    1.在路由配置文件:app-routing.module.ts中配置子路由

    {path: 'stock4/:id', component: Stock4Component,data:[{name: 'Smith'}], children: [
        {path: '', component: SellerListComponent}, // 默认加载父组件路由时,加载该子组件。
        {path: 'buyer/:id', component: BuyerListComponent}  //当路由为/stock/1/buyer/id时,加载该子组件。
      ]}  
    

    2.在父组件添加插座:

    <router-outlet></router-outlet>
    

    3.在父组件添加跳转:

    <button [routerLink]="['./']">卖家列表</button>
    <button [routerLink]="['./buyer', 343]">买家列表</button>
    // 注意:跳转的路径是以父组件为基准的,所以在路由前必须加上'./',否则就是以 '' 为基准了。
    

    注意: (1)子路由是可以无限嵌套下去的。
    (2)同一个组件可以有多个路由。

    第六节 辅助路由:

    1.定义插座:

    <router-outlet></router-outlet>
    <router-outlet name="aux"></router-outlet>   // 为插座添加name
    

    2.定义路由:

     {
        path: 'consult',
        component: ConsultComponent,
        outlet: 'aux'   // 指定路由插座为‘aux’
    }
    

    该组件将会加载在辅助路由 'aux' 中

    3.在辅助插座上显示相应组件:

    <a [routerLink]="[{outlets: {primary: 'home',aux: 'consult'}}]">开始咨询</a> 
    // 设置路由指定的插座,同时基础路由为:home,primary可以不设置
    // 辅助插座的指定路由为 'consult'
    

    4.清空辅助插座内容:

    <a [routerLink]="[{outlets: {aux: null}}]">结束咨询</a>
    

    表示辅助插座aux加载的组件为空,即清空辅助插座内容

    第七节 路由守卫

    1.canActivate: 跳转到路由之前的情况判断
    (1).定义canActivate路由守卫:

    permission.guard.ts:
    import {CanActivate} from "@angular/router";
    export  class  PermissionGuard  implements CanActivate {
        canActivate() {
            let hasPermission:boolean = Math.random()< 0.5;
            if(!hasPermission) {
                console.log('用户无权访问此股票详情');
            }
            return hasPermission;
        }
    }
    

    (2).引入:
    app.module.ts

    ...
    providers: [PermissionGuard],
    ...
    

    (3)应用:

    app-routing.module.ts :
    
    {
    path: 'stock/:id',
    component: StockComponent,
    data: [{isPro: true}],
    children: [
      {path: '',component: BuyerListComponent},
      {path: 'seller/:id',component: SellerListComponent}
    ],
    canActivate: [PermissionGuard],  // 应用
    

    2.canDeactivate: 离开路由后的情况判断

    (1) 定义canDeactivate路由守卫:

    focus.guard.ts
    import {CanDeactivate} from "@angular/router";
    import {Stock4Component} from "../stock4/stock4.component";
    
    export class FocusGuard implements CanDeactivate<Stock4Component> { // 指定需要保护的组件
      canDeactivate(component:Stock4Component) {
        if(component.focus()) {  // 引入组件方法
          return true;
        }else {
          return window.confirm('不关注吗?');
        }
      }
    }
    注意:因为是离开前的路由判断,所以可以利用组件信息
    

    (2).引入:
    app.module.ts

    ...
    providers: [FocusGuard],
    ...
    

    (3)应用:

    app-routing.module.ts :
    
    {
    path: 'stock/:id',
    component: StockComponent,
    data: [{isPro: true}],
    children: [
      {path: '',component: BuyerListComponent},
      {path: 'seller/:id',component: SellerListComponent}
    ],
    canActivate: [FocusGuard],  // 应用
    

    (4)在stock4.component.ts中定义方法:

    focus() {
       return this.isFocus;
     }
    

    3.路由守卫resolve: 在跳转路由之前,获取路由数据,避免在没有获取数据之前,出现错误。
    作用: 对数据进行判断,从而进行相应的跳转。
    (1).准备工作:

    stock.component.ts
    将stock 数据转为对象:
    
    private stock: Stock;
    export class Stock {
      constructor(public id: number, public name: string) {
      }
    }
    

    (2).创建 stock的resolve守卫:

    stock.resolve.ts
    
    @Injectable()  // 引入依赖注入 
    
    export class StockResolve implements Resolve<Stock> {  // 引入Stock对象
        constructor(private router: Router) {   // 引入Router 模块
    }
    
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Stock | Observable<Stock> | Promise<Stock> {
        let id = route.params['id'];   // 接收传入数据
        if (id == 1) {
            return new Stock(1, 'IBM');   // 创建Stock 对象
    
        } else {
            this.router.navigate(['/home']);  // 导航到home
        }
    }
    

    (3).引入:

    app.module.ts
    providers: [StockResolve]
    

    (4). 在路由定义中引入该路由守卫

    resolve: {
      stock: StockResolve
    }
    

    (5).在stock.component.ts中接收路由守卫处理后的数据

    this.routeInfo.data.subscribe((data: { stock: Stock }) => {
      this.stock = data.stock;
    });
    

    相关文章

      网友评论

        本文标题:Angular路由

        本文链接:https://www.haomeiwen.com/subject/eyfvtftx.html