Angular4.0 路由导航的使用

1. a 链接的 routerLink 属性展示对应的子组件内容。

命令 ng new routeDemo --routing  新建一个具有路由功能的项目。

在app.module 中配置

path 路径不能  /  开头, 方便多页面导航用到相对路径和绝对路径。

路由根据匹配优先按照顺序来匹配,可在最后添加一个通配符的路由匹配。

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {HomeComponent} from "./home/home.component";
import {DetailComponent} from "./detail/detail.component";

// 根路由:
const routes: Routes = [
  {path:'',component: HomeComponent},
  {path:'product',component: DetailComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

在html 中 路径 / 开头,表示导航到一个根路由。app.html  在 router-outlet 显示展示的内容。

routeLink 用于导航带一个url 地址。参数时一个数组,后面可以跟一些要传的参数。

<a [routerLink]="['/product']" >商品详情</a>
<a [routerLink]="['']" ></a>主页
<router-outlet></router-outlet>

2. 传递参数

2.1查询参数 传参写在queryParams 中 http://localhost:4200/product?id=1

<a [routerLink]="['/product']" [queryParams]="{id:1}" >商品详情</a>

在对应的商品组件中的 product.compoent.ts  方法接收传递的值。

2.Router对象的 navigate 方法跳转

根据   angular 数据绑定之事件绑定。

3.ActivedRoute来匹配

ActivedRoute.param[id]   得到参数值

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {

  private productId:number;

  constructor(private route:ActivatedRoute) {

  }

  ngOnInit() {
    this.productId=this.route.snapshot.queryParams["id"];
  }


}

snapshot (快照)方法导致若之前请求过此路径,用snapshot 请求时将得到的是原来的值。

这是由于在创建组件后不会被再次创建 ,ngOnit() 方法创建一次,productId 保持第一次创建时的值。

解决方法: 参数订阅

声明一个匿名的函数来处理传进入的参数。

ngOnInit() {
  this.route.params.subscribe((params:Params) => this.productId=params["id"]);

}

2.2 从url 中取   app-routing 设置。

const routes: Routes = [
  {path:'',component: HomeComponent},
  {path:'product/:id',component: DetailComponent}
];

<a [routerLink]="['/product',1]" >商品详情</a>

3.重定向路由   redirectTo:

const routes: Routes = [
  {path:'',redirectTo:'home',pathMatch:'full'},
  {path:'home',component: HomeComponent},
  {path:'product/:id',component: DetailComponent}
];

4. 子路由配置

const routes: Routes = [
  {path:'',redirectTo:'home',pathMatch:'full'},
  {path:'home',component: HomeComponent},
  {path:'product/:id',component: DetailComponent,children:[{path:'',component:ProductDetailComponent},{

      path:'seller/:id',component:SellerComponent

    }]

  }
];
import {ActivatedRoute, Params} from "@angular/router";

@Component({
  selector: 'app-seller',
  templateUrl: './seller.component.html',
  styleUrls: ['./seller.component.css']
})
export class SellerComponent implements OnInit {

  private sellerId:number;
  constructor(private route:ActivatedRoute) { }

  ngOnInit() {
    this.route.params.subscribe((params: Params) => this.sellerId=params["id"]);
  }

}

5. 辅助路由

声明辅助路由在主路由的旁边。name属性。 这些都需要在route 中标明。

在a 链接中定义跳转到 chat 路径的对象 [outlets : {aux: chat}],可添加primary 主路由,表示当跳转到辅助路由时,对应的主路由是什么。

const routes: Routes = [
  {path:'',redirectTo:'home',pathMatch:'full'},
  {path:'chat',component: ChatComponent,outlet:'aux'},
  {path:'home',component: HomeComponent},
  {path:'product/:id',component: DetailComponent,children:[{path:'',component:ProductDetailComponent},{
      path:'seller/:id',component:SellerComponent
    }]
  },

];
<div class="pro">
  <h1>
    Welcome to {{title}}!
  </h1>

  <a [routerLink]="['/product',1]" >商品详情</a>
  <a [routerLink]="['/home']" >主页</a>

  <a [routerLink]="[{outlets: {primary: 'home',aux: 'chat'}}]">开始聊天</a>
  <a [routerLink]="[{outlets: {aux: null}}]">结束聊天</a>
  <input type="button" value="商品详情" (click)="toDetail()" >
<router-outlet></router-outlet>
</div>

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

 

6. 路由守卫

用于一些权限控制,进入某页面激活,退出某页面等。

定义一个类,继承 CanActivate 实现 canActivate 方法,返回true 时,通过。false 不通过。

import {CanActivate} from "@angular/router";

export class LoginGuard implements CanActivate{
  canActivate() {
    let login= Math.random()<0.5;
     if (login){
       console.log('请登录');
     }
     console.log(Math.random()<0.5);
     return !login;
  }
}

在路由中配置,即加在想要拦截的路径后面。

const routes: Routes = [
  {path:'',redirectTo:'home',pathMatch:'full'},
  {path:'chat',component: ChatComponent,outlet:'aux'},
  {path:'home',component: HomeComponent},
  {path:'product/:id',component: DetailComponent,children:[{path:'',component:ProductDetailComponent},{
      path:'seller/:id',component:SellerComponent
    }],canActivate:[LoginGuard],canDeactivate:[LoginOutGuard]
  },

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[LoginGuard,LoginOutGuard]
})
export class AppRoutingModule { }

canDeactive 为退出时拦截,当点击确认退出时,返回 true.

import {CanDeactivate} from "@angular/router";
import {ProductDetailComponent} from "../product-detail/product-detail.component";

export class LoginOutGuard implements CanDeactivate<ProductDetailComponent>{
  canDeactivate(component: ProductDetailComponent) {
    return window.confirm("确定要退出商品详情页面吗");
  }
}

7. resolve 守卫解决显示延迟导致显示为空的情况。(进入组件之前拿到数据,若拿不到数据,则跳转到相关组件)

resolve 守卫首先去服务器上抓取信息,然后返回抓取的信息。

定义一个类ProductResolve 实现 Resolve<T>类,重写resolve 方法(route : ActivatedRouteSnapShot 参数)

//ActivatedRouteSnapShot =this.router.snapshot

定义类的上方需要用一个注解注入(由构造函数注入)。component 不需要注入是由于 component 注解已经继承了@injectable() 装饰器

ProductResolve 解析 product.product 为传入的参数名字。

resolve: { product : ProductResolve}

 

若不加注解注入。会报如下错误:

client:139 C:/Users/SAMSUNG/Desktop/routeDemo/routeDemo/src/app/guard/productResolve.guard.ts (7,18): Cannot find name 'ActivatedRouteSnapshot'.

client:139 C:/Users/SAMSUNG/Desktop/routeDemo/routeDemo/src/app/guard/productResolve.guard.ts (7,49): Cannot find name 'RouterStateSnapshot'.

client:139 C:/Users/SAMSUNG/Desktop/routeDemo/routeDemo/src/app/guard/productResolve.guard.ts (7,71): Cannot find name 'Observable'.

client:139 C:/Users/SAMSUNG/Desktop/routeDemo/routeDemo/src/app/guard/productResolve.guard.ts (10,14): Supplied parameters do not match any signature of call target.

 

import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from "@angular/router";

import {Observable} from "rxjs";
import {Product} from "../product-detail/product-detail.component";
import {Injectable} from "@angular/core";


// @ts-ignore
@Injectable()
export class ProductResolveGuard implements Resolve<Product>{
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product> | Promise<Product> | Product {

    let id: number = route.params["id"];
    if (id == 1) {
      return new Product(1, "metu");
    }
    return undefined;
  }

const routes: Routes = [
  {path:'',redirectTo:'home',pathMatch:'full'},
  {path:'chat',component: ChatComponent,outlet:'aux'},
  {path:'home',component: HomeComponent},
  {path:'product/:id',component: DetailComponent,children:[{path:'',component:ProductDetailComponent},{
      path:'seller/:id',component:SellerComponent
    }],canActivate:[LoginGuard],canDeactivate:[LoginOutGuard],resolve: {product: ProductResolveGuard}
  },

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[LoginGuard,LoginOutGuard,ProductResolveGuard]
})
export class AppRoutingModule { }

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值