angular学习之路由(一)

一、路由相关对象介绍

1.Routes:路由配置,保存着哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示组件。(在模块中配置,可在主模块中配置,也可在生成项目时使用ng new 项目名 –routing来生成一个带routing配置模块的项目,并自动导入到主模块);
用法示例(path中不需要‘/’):

const routes:Routes=[
    {path: '', redirectTo: '/home',pathMatch: 'full'}, //重定向路由
    {path: 'home',component: HomeComponent},
    {path: 'xxx',component: XxxComponent},
{path: '**',component: 404PageComponent} //通配符,一般放在此集合的最后一项,匹配此应用中没有的路径,导航至指定的404页面]
@NgModule({
    imports:[RouterModule.forRoot(routes)]
})

2.RouterOutlet: 在HTML中标记路由内容呈现位置的占位符指令;(位于模板中);
用法示例:

<router-outlet></router-outlet> //对应路由的内容显示在此标签的下方。

3.Router: 负责在运行时执行路由的对象,可以通过调用其navigate()navigateByUrl()方法来导航到一个指定的路由;
用法示例:

//模板中


//组件控制器中
Constructor(private router: Router){ //在控制器参数中导入Router对象
}
nav(){
    this.router.navigate(['/home']); //参数为数组格式,可用来传递数据
    this.router.navigateByUrl( '/home');
}

4.RouterLink: 在HTML中声明路由导航用的指令(位于模板中);
用法示例:

<a [routerLink]="["/home"]">主页a>  //值为一个数组,路径中需要'/'

5.ActivatedRoute: 当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等。

二、在路由时传递数据

1.在查询参数中传递数据

/product?id=1&name=2   => ActivatedRoute.queryParams[id]

模板中声明路由导航链接的标签内传递:

<a [routerLink]="['/xxx']" [queryParams]="{id:1}">导航链接a>

目标组件的控制器中接收:
在路由目标组件中,定义一个属性textKey,在组件构造器中引入ActivatedRoute对象命名为routeInfo

ngOnInit(){
    this.textKey=this.routeInfo.snapshot.queryParams["id"];
}

2.在路由路径中传递数据

{path:/product/:id}  =>  /product/1  => ActivatedRoute.params[id]

修改路由配置:

{path: '/xxx/:id',component: XxxComponent}

模板中声明路由导航链接的标签内传递:

<a [routerLink]="['/xxx', 1]">导航链接a>

模板中绑定组件中方法传递:

<a (click)=toDetail()>点击传递参数a>

组件控制器中方法传递:
在组件构造器中引入Router对象命名为router

toDetail() {
    this.router.navigate(['/xxx', 2]);
}

目标组件的控制器中接收:
在路由目标组件中,定义一个属性textKey,在组件构造器中引入ActivatedRoute对象命名为routeInfo
参数快照snapshot (不同组件间跳转时可用此方法传递,组件内传递数据因组件只初始化一次,此方法只能调用1次,无法多次传递,但相对节约资源,速度更快)

ngOnInit(){
    this.textKey=this.routeInfo.snapshot.params["id"];
}

参数订阅subscribe (组件内传递数据,初始化的时候订阅params,可多次传递,每当params改变时都会传递)

ngOnInit(){
    this.routeInfo.params.subscribe((params: Params) => this. textKey=params['id']);
}

3.在路由配置中传递数据

{path:/product,component:ProductComponent,data:[{isProd:true}]}
=> ActivatedRoute.data[0][isProd]

路由配置中传递:(data是一个数组)

{path: '/xxx',component: XxxComponent,data:[{isPro:true}]}

目标组件的控制器中接收:
在路由目标组件中,定义一个属性isPro,在组件构造器中引入ActivatedRoute对象命名为routeInfo

ngOnInit(){
    this.isPro=this.routeInfo.snapshot.data[0]["isPro"];
}

三、重定向路由

重定向路由:在用户访问一个特定的地址时,将其重定向到另一个指定的地址
例如:

    www.aaa.com    =>    www.aaa.com/products
    www.aaa.com/x    =>    www.aaa.com/y

路由配置时,路径名path和组件名称最好一一对应,一目了然。
如:
{path: "home", component: HomeComponent}

一般路由配置中第一个路径设置为空字符串,并重定向到主页
1.路由路径为空时重定向到主页

{path: "",redirectTo: "/home", pathMatch: "full"}

2.路由路径xx开头时重定向到主页

{path: "xx",redirectTo: "/home", pathMatch: "prefix"}

四、子路由

子路由配置语法如下:(子路由是个数组)

{ path: "home", component: HomeComponent,
    children:[
        {path: "", component: XxxComponent},
        {path: "/yyy", component: YyyComponent}
    ]
}

1.子路由可多级嵌套
2.路由在模块中配置,路由信息和组件是分离的,可以通过路由配置将一个组件配置成另一个组件的子组件,同时也可以为其配置一个主路由,为应用开发提供了灵活性。

五、辅助路由

声明一个辅助路由需要三步:
1.组件模板中:

<router-outlet></router-outlet>  //显示主路由组件
<router-outlet name= “aux”></router-outlet>  //显示辅助路由组件

2.路由配置内:

// 以下配置xxx和yyy组件只能在name=‘aux’的路由插座上显示
{path: "xxx", component: XxxComponent, outlet: "aux"}, 
{path: "yyy", component: YyyComponent, outlet: "aux" }

3.组件模板中:

//点击此链接在主路由插座显示home组件,在辅助路由插座显示xxx组件 
<a routerLink= "['/home',{outlets:{aux: 'xxx'}}]">xxx</router-outlet>
//点击此链接在主路由插座显示product组件,在辅助路由插座显示yyy组件
<a routerLink= "['/product',{outlets:{aux: 'yyy'}}]">yyy </router-outlet>
//点击此链接在主路由插座显示product组件,在辅助路由插座什么都不显示
<a routerLink= "['/product',{outlets:{aux: null}}]">yyy </router-outlet>
//点击此链接在主路由插座显示home组件,在辅助路由插座显示yyy组件
<a routerLink= "[{outlets:{primary:'/home', aux: yyy}}]">yyy </router-outlet>

六、路由守卫

拦截器,进入路由之前和离开路由之前实现一些逻辑。
三种:
1.CanActivate:处理导航到某路由的情况。(在导航到某个路由之前执行一些判断后再觉得让不让此导航生效)
用法示例:
① 新建guard(存放各种路由守卫)文件夹,在内部新建一个permission.guard.ts文件:

export class PermissionGuard implements CanActivate{
    canActivate(){
        var hasPremission:Boolean=Math.random()<0.5;
        if(!hasPremission){
            alert('vip才可以访问哦!');
        }
        return hasPremission;
    }
}

② 路由配置中:(canActivate: [ ]为一个数组,可配置多个守卫,依次调用,其中一个返回false就无法进入该路由)

{path: '/xxx',component: XxxComponent,canActivate: [PermissionGuard]}

③ 模块中:

providers:[PermissionGuard]  //帮助实例化

2.CanDeactivate:处理从当前路由离开的情况。(当用户从当前路由离开时执行一些逻辑)
用法示例:
① 新建一个focus.guard.ts的文件:

//接口的泛型内指定你要保护的路由对应的组件XxxComponent。
export class FocusGuard implements CanDeactivate<XxxComponent>{
    canDeactivate(component:XxxComponent){
        var hasPremission:Boolean=Math.random()<0.5;
        if(!hasPremission){
            window.confirm('确定要离开吗!');
        }
        return hasPremission;
    }
}

②路由配置中:(canDeactivate: [ ]为一个数组,可配置多个守卫,依次调用,其中一个返回false就无法离开该路由)

{path: '/xxx',component: XxxComponent,canDeactivate: [FocusGuard]}

③ 模块中:

providers:[FocusGuard]  //帮助实例化

3.Resolve:在路由激活之前获取路由数据。(可帮助提高用户体验)
用法示例:
①新建一个resolve.guard.ts的文件:

//接口的泛型内指定你要获取的数据的类型
@Injectable()//此注解的作用是让依赖注入生效
export class ResolveGuard implements Resolve<Info> {

//依赖注入
  constructor(private router: Router) {

  }
//通过ActivatedRouteSnapshot对象可拿到路由参数
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable|Promise|ProductComponent {

    let id:number = route.params['id'];

    if(id == 1) {
      return new Info(‘1’, ‘张三’);
    }else{
      this.router.navigate(['/home']);
      return undefined;
    }
  }
}

② 路由配置中:(resolve:{ }为一个对象,可配置多个守卫)

//当进入'/xxx'这个路由时,要携带一个数据info,info的值由ResolveGuard这个路由守卫提供。
{path: '/xxx',component: XxxComponent,resolve: {info: ResolveGuard }}

③ 模块中:

providers:[ResolveGuard]  //帮助实例化

④ 对应组件控制器中:

export class XxxComponent implements OnInit {

  private info:Info;

  constructor(private routeInfo: ActivatedRoute) {

  }

  ngOnInit() {
        this.routeInfo.data.subscribe((data:{info:Info})=>{
            this.info=data.info
            });

  }
}
export class Info {

  constructor(public id:number,
              public name:string){}
}

⑤对应组件模板中:

{{info.id}}{{info.name}}

部分路由相关内容先总结到这里,后续学到新的知识会继续总结,如有错误之处,欢迎指出!

你可能感兴趣的:(angular学习笔记)