我爱编程

Angular路由

2018-02-22  本文已影响0人  咖啡浮点

第二节:路由介绍

1.生成新项目

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

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

Routes、RouteOutlet、Router、RouterLink、ActivatedRoute


routerProperty.png

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;
});
上一篇下一篇

猜你喜欢

热点阅读