【Angular】路由 Route导航

在路由开始之前,先补一下Angular的一些基础知识:
概念:

  • 组件:是Angular应用的基础构建块,可以理解为是一段带有逻辑和数据的html
  • 模块:用来将应用中不同的部分组织成一个Angular框架,可理解的单元
  • 指令:允许向html元素中添加自定义行为
  • 服务:用来封装可重用的业务逻辑

框架认识:


Angular Route导航
用到路由时,最常用的对象有

  • Routes:路由配置,保存哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示组件
  • RouterOutlet:在HTML中标记路由内容呈现位置的占位符指令
  • Router:负责在运行时执行路由的对象,可通过调用期navigate()和navigateByUrl()方法来导航到一个指定的路由
  • Routerlink:在HTML中声明路由导航用到的指令
  • ActivatedRoute:当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等
一:定义路由
{
    path: '',
    component:HomeComponent
  },
  {
    path:'product',
    component:ProductComponent
   }
  • 以上定义了两个路由:path:‘’表示默认路由自动跳转到HomeComponent组件
  • path:‘’路径不能以‘/’开头,方便在导航时使用相对和绝对路径

      定义根路由:RouterModule.forRoot(routes)

二:路由导航类型


      使用命令导航[routerLink]
            如导航到home主页<a [routerLink]="['/product']">商品页面</a>


      使用代码导航
            1.先在构造函数中添加Router:
                  constructor(private router:Router){}
            2.在指定方法中添加导航代码:
                  this.router.navigate(['/product']);


三:在html中定位插座的位置

       <router-outlet></router-outlet >

以上步骤以能成功导航

四:通用路由

      为了防止程序崩溃,所以设置一个通用路由,即当输入不存的URL时,导航到指定页面

{
    path:'*',
    component:Code404Component
  }

       因为路由具有先匹配者优先的原则,所以配置路由时通用路由应该放在所有路由的后面

五:在路由中传递数据


      在URL中传递数据
      1.路由配置

{
    path:'product/:id',
    component:ProductComponent
}

      2.在跳转路由入口时传递实际的数值
            [routerLink]="['/product',1]"
            或
            this.router.navigate(['/product',1])


      在查询参数中传递数据
      1.[routerLink]="['/product']" [queryParams]="{id:1}"
      2.接收数据
            先在构造函数中声明ActivatedRoute对象
            constructor(private routeInfo:ActivatedRoute) { }
            然后在ngOnInit()接收参数

  ngOnInit() {
  //参数快照方式
     this.productId = this.routeInfo.snapshot.queryParams["id"];
    //参数订阅方式,写在匿名函数中
    this.routeInfo.params.subscribe((params:Params) => this.productId=params["id"]);
   }

      使用参数订阅方式,是因为当有多个方式跳转到同一路由时,但是传递的参数不同,但是ngOnInit()只有在第一次创建对象时才执行,由于我们接收参数时又是写在ngOnInit()里面的,所以如果使用参数快照的方式,只有第一次导航路由时参数被传进来了,以后再导航该路由时,参数都传不进来了,因为不执行ngOnInit()方法了


六:重定向路由

      使用情况:
             在用户访问一个特定的地址时,将其重定向到另一个指定的地址
       如:
              www.aaa.com => www.aaa.com/product
              ww.aaa.com/x => www.aaa.com/y

      比如:在设置路由时,默认空路径,导航到HomeComponent,但是这样不符合规范,路径名最好是组件名,

{
    path: 'home',
    component:HomeComponent
  }

      然后可以用路由重定向,当到默认路径下时,重导向到home路径下

   {
    // 路由重定向
    path:'',
    redirectTo:'/home',
    pathMatch:'full'
  }
七:子路由

      1.想给谁添加子路由就在谁的路由配置下添加children
      如:

    path:'product',
    component:ProductComponent,
    // 定义子路由
    children:[
      {
        path:'',
        component:ProductDescComponent
      }
    ]

       2.在父路由的html中添加一个子路由的插座

八:主路由和辅助路由

      1.配置辅助路由出口:一个页面只能有一个路由插座,这是还想一块显示隐藏多个组件,这时就可以定义一个辅助路由

<router-outlet></router-outlet >
<router-outlet name="aux"></router-outlet>

       辅助路由与主路由不同的是,要添加一个name属性

       2.然后配置路由

 {
    path:'chat',
    component:ChatComponent,
    outlet:'aux'
  } 

      3.最后定义辅助路由入口
             [routerLink]="[{outlets:{primary:'home', aux:'chat'}}]"
      要表明是谁的辅助路由,即主路由:primary

九: 路由守卫

  • CanActivate:处理导航到某路由的情况
  • CanDeactivate:处理从当前路由离开的情况
  • Resolve:在路由激活之前获取路由数据

CanActivate:在满足一定条件下才能进入下一个路由
      1.首先定义守卫,实现CanActivate接口

export class LoginGuard implements CanActivate{
    canActivate(){
        let loggedIn:boolean = Math.random() < 0.5;
        if(!loggedIn){
            console.log("用户未登录");
        }
        return loggedIn;
    }
}

      2.然后在要跳转到的路由配置中,添加canActivate:[LoginGuard]


CanDeactivate<返回到的路由组件> :处理从当前路由离开的情况
      1.首先定义守卫,实现CanDeactivate<>接口

export class UnsavedGuard implements CanDeactivate<ProductComponent>{
    canDeactivate(component: ProductComponent){
        return window.confirm("你还没有保存,确定要离开吗?");
    }
}

      2.然后在要跳转到的路由配置中,添加canDeactivate:[UnsavedGuard]


Resolve<返回的东西>:在路由激活之前获取路由数据
      1.定义守卫

@Injectable()
export class ProductResolve implements Resolve<Product>{

    constructor(private router:Router){  }    
    resolve(route:ActivatedRouteSnapshot,state:RouterStateSnapshot):Observable<Product>|Promise<Product>|Product{

        let productId:number = route.params["id"];

        if(productId == 1){
            return new Product(1,"iPhone7");//返回Product对象
        } else {
            this.router.navigate(['/home']);
            return undefined;
        }
    }
注意项:
导入@Injectable()装饰器
构造函数中定义Router对象
返回的是Product对象,所以要在要跳转到的路由的组件中定义Product类
export class Product {
  constructor(public id:number,public name:string){}
}

      2.然后在要跳转到的路由配置中,添加 resolve:{ product:ProductResolve}
      3.最后在要激活的路由控制器中接收数据

export class ProductComponent implements OnInit {

  private productId:number;
  private productName:string;

  constructor(private routeInfo:ActivatedRoute) { }

  ngOnInit() {
      //订阅传进来的数据
    this.routeInfo.data.subscribe((data:{product:Product}) =>{
      this.productId = data.product.id;
      this.productName = data.product.name;
    });
  }
}

      设置Resolve路由的原因:防止在有插值绑定的html中,在数据没常见来时页面已加载的情况


例子

下面是有关路由知识的例子:
      链接: https://pan.baidu.com/s/1nvj7gmd 密码:rsak

总结

完成一个路由跳转的步骤:

  1. 定义路由插座
  2. 配置路由
  3. 定义路由入口
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值