angularcli的路由的使用

一、安装路由文件到模版

首先,用ngcli新建一个配置好路由文件名为“ngRouter”的项目:

在命令工具输入

ng new ngRouter --routing

安装完毕后,会在项目文件中的src/app中看到一个名为“app-routing.module.ts”的文件,

里面的代码是这样的:

import{NgModule}from'@angular/core'; //第一行
import{Routes,RouterModule}from'@angular/router'; //第二行
const routes:Routes=[]; //第三行
@NgModule({ //第四行
imports:[RouterModule.forRoot(routes)], //第五行
exports:[RouterModule] //第六行
})
export class AppRoutingModule { } //第七行

代码中的第一行是导入NgModule,第二行导入配置路由用的Routes和RouterModule类,第三行声明一个Routes类型的常量,用以配置路由的参数,第五行是将定义的路由注入到NgModule中,第七行是本文件的出口,会在“app.module.ts”文件中导入:

二、新建两个用于演示的组件

在命令行工具中输入

在项目中生成了两个组件(demo1和demo2)

三、实现简单的路由

到“app-routing.module.ts”文件,给routes常量赋值,即在中括号中输入内容,routes是一个数组,元素可以看作是每一个要配置的路由。在这,分别给demo1和demo2配置路由,输入内容如下:

在app组件中写入可以实现跳转的a标签,“app.component.html”的内容写成:

接着运行在浏览器中(在命令行工具输入npm start)

3.1路由重定向

如果需要进入主页就开始显示组件demo1的内容,则在“app-routing.module.ts”配置对应的属性,如下:

3.2按钮实现跳转

不论是什么元素的什么事件,都可以触发路由跳转。用简单的按钮点击事件作示范:

首先,在“app.component.html”中添加一个按钮:

接着,在“app.component.ts”中定义点击相对应的函数(这里是"linkToDemo2"):

注意:需要导入Router,然后在构造函数中注入,写在navigate的参数是个数组。

3.3无定义路由跳转到404页面

在现实中,如果用户输入路由错误或没有定义的路由,这时,应该跳转到一个404页面。项目中,实现的步骤如下:

1、写好一个404页面组件,并写上要显示的内容。

2、在路由中设置好配置

关键: 这里用到了“**”作通配符,路由是按顺序找组件的,一定要把这个对象放到最后。

3.4路由传参的应用

3.4.1在路由路径中传递数据

在路由中定义一个参数,用户输入是什么值,那么这个参数就被定义成什么值,简单的应用如下:

“demo1.component.ts”:

其次。修改路由链接的时候,让这个链接在跳转的时候携带参数

demo1
or
demo1

另外还通过调用 navigate() 方法传一样的参数也可以

this.router.navigate(['/demo1',456]);

如果在同一个组件上跳转的时候传递的值不会发生改变,可通过以下的方法来解决

this.routerInfo.params.subscribe((params: Params)=>this.userId = params['id']);

3.4.2 在查询参数中传递数据

然后,在“demo1.component.ts”中写成:

3.4.3在路由配置中传递数据

在路由配置文件中,加上属性data:

在“demo1.component.ts”中写成:

四、子路由

首先在路由配置中添加 children 属性,比如有用户主组件下有两个子组件,分别是 admin 和 guest,那么路由中的配置如下

{
path: 'user/:id', component: UserComponent, data: [{isExists: true}], children: [
{path: '', component: AdminComponent},
{path: 'guest/:id', component: GuestComponent}
]

然后在用户的模板中添加以下代码:

admin guest

五、辅助路由

比如说像在页面中显示一个在线咨询的组件,不论在哪个页面都会显示它。

首先当然是创建名为“connult”的咨询组件,至于模板里面呈现的视图标签这里就不多写了

在主模板“app.component.html”中添加以下的代码

// 切换显示与不显示在线咨询组件
start connult
end connult
// 路由插座定义 name 属性

然后在路由配置里面加入以下路由代码

// 这里的 aux 就是在 router-outlet 上面定义的 name 属性
{path: 'connult', component: ConnultComponent, outlet: 'aux'},

 

同时还可以来控制主路由,代码如下:

start connult
end connult
// 定义 primary:'home' 之后
// 不管主插座上显示的是什么
// 当点击 start connult 链接时,都要到跳到 home 这个路径上去显示 home 里面内容

六、路由守卫

6.1、CanActivate:处理导航到某路由的情况

在这里用是否有访问权限来举例。

首先在项目中建立一个名“guard”的文件夹,然后在里面建立一个名为:“PermissionGuard”的 TS 文件。里面的代码如下:

import {CanActivate} from "@angular/router";
export class PermissionGuard implements CanActivate {
  canActivate() {
    // 在这里随机产生是否有权限访问的一个判断
    var hasPermissionGuard:boolean = Math.random() < 0.5;
    if (!hasPermissionGuard) {
      console.log('无权访问');
    }
    return hasPermissionGuard;
  }
}

路由守卫已经写出来了,然后将这个路由守卫配置到路由配置上去。

比如在访问用户组件时加上这个权限的判断,代码如下:

{
  path: 'user/:id', component: UserComponent, data: [{isExists: true}], children: [
  {path: '', component: AdminComponent},
  {path: 'guest/:id', component: GuestComponent}
],
  // canActivate 是一个数组
  canActivate: [PermissionGuard]
}

“PermissionGuard”是一个需要实例化的东西,所以要在 AppModule 中进行引入:

import {PermissionGuard} from "./guard/permission.guard";

然后在“NgModule”的“providers”中加上“PermissionGuard”代码如下:

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    UserComponent,
    Code404Component,
    AdminComponent,
    GuestComponent,
    ConnultComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [PermissionGuard],
  bootstrap: [AppComponent]
})

6.2、CanDeactivate:处理从当前路由离开的情况

在这里用是否关注的实例。

同样在名“guard”的文件夹中建立一个名为“FocusGuard”的TS文件,代码如下:

import {CanDeactivate} from "@angular/router";
import {UserComponent} from "../user/user.component";
export class FocusGuard implements CanDeactivate {
  // CanDeactivate 中会将你的 UserComponent 组件引入
  canDeactivate(component: UserComponent) {
    // 如果没有关注的一个判断
    if (component.isFocus()) {
      return true;
    } else {
      window.confirm("不关注你就留下吧");
    }
  }
}

然后在路由配置里面加上“canDeactivate: [FocusGuard]”:

import {FocusGuard} from "./guard/focus.guard";
const routes: Routes = [
 {path: '', redirectTo: '/home', pathMatch: 'full'},
 {path: 'home', component: HomeComponent},
 {path: 'connult', component: ConnultComponent, outlet: 'aux'},
 {path: '**', component: Code404Component},
 {
 path: 'user/:id', component: UserComponent, data: [{isExists: true}], children: [
 {path: '', component: AdminComponent},
 {path: 'guest/:id', component: GuestComponent}
 ],
 // canActivate 是一个数组
 canActivate: [PermissionGuard],
 canDeactivate: [FocusGuard]
 }
];

然后在“NgModule”的“providers”中加上“FocusGuard”代码如下:

import {FocusGuard} from "./guard/focus.guard";
@NgModule({
 declarations: [
 AppComponent,
 HomeComponent,
 UserComponent,
 Code404Component,
 AdminComponent,
 GuestComponent,
 ConnultComponent
 ],
 imports: [
 BrowserModule,
 AppRoutingModule
 ],
 providers: [PermissionGuard, FocusGuard],
 bootstrap: [AppComponent]
})

然后在 UserComponent 的控制 器中写入一个调取是否关注的方法,代码如下:

export class UserComponent implements OnInit {

  private userId:number;
  private focus:boolean = false;
  ……
  isFocus() {
    return this.focus;
  }

}

再在 UserComponent 的模板中加入一个“关注”的按钮,代码如下:

6.3、Resolve:在路由激活之前获取路由数据

这是一个被称为“Resolve守卫”,用它可以来解决什么样的问题,以下通过一个例子来说明。

首先在 UserComponent  中加入以下高亮的代码

export class UserComponent implements OnInit {

  private userId:number;
  private user:User;
  private isExists:boolean;
  private focus:boolean = false;

  constructor(private routerInfo:ActivatedRoute) { }

  ngOnInit() {
    this.routerInfo.data.subscribe((data:{user:User})=>{
      this.user = data.user;
    });
    this.routerInfo.params.subscribe((params: Params)=>this.userId = params['id']);
    // this.userId = this.routerInfo.snapshot.params["id"];
    this.isExists = this.routerInfo.snapshot.data[0]['isExists'];
  }

  isFocus() {
    return this.focus;
  }

}
// 声明一个 User 的模型
export class User {
  constructor(public id:number,public name:string){}
}

然后在名“guard”的文件夹中建立一个名为“FocusGuard”的TS文件,代码如下:

import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from "@angular/router";
import {User} from "../user/user.component";
import {Observable} from "rxjs";
import {Injectable} from "@angular/core";
@Injectable()
export class UserResolve implements Resolve {
  constructor(private  router: Router) {
  }
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | User {
    let id = route.params['id'];
    // 在这里判断访问的用户 id 是否为 1,
    // 如果不是就跳转到首页
    if (id == 1) {
      return new User(1, 'zhang san');
    } else {
      this.router.navigate(['/home']);
      return undefined;
    }
  }
}

然后在路由配置里面加上:

import {UserResolve} from "./guard/user.resolve";
const routes: Routes = [
  {path: '', redirectTo: '/home', pathMatch: 'full'},
  {path: 'home', component: HomeComponent},
  {path: 'connult', component: ConnultComponent, outlet: 'aux'},
  {path: '**', component: Code404Component},
  {
    path: 'user/:id', component: UserComponent, data: [{isExists: true}], children: [
    {path: '', component: AdminComponent},
    {path: 'guest/:id', component: GuestComponent}
  ],
    // canActivate 是一个数组
    // canActivate: [PermissionGuard]
    // canDeactivate: [FocusGuard]
    resolve:{
      user:UserResolve
    }
  }
];

然后在“NgModule”的“providers”中加上“PermissionGuard”代码如下:

import {UserResolve} from "./guard/user.resolve";
@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    UserComponent,
    Code404Component,
    AdminComponent,
    GuestComponent,
    ConnultComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [PermissionGuard, FocusGuard, UserResolve],
  bootstrap: [AppComponent]
})

http://blog.pkcms.cn/angular-router/ 

https://blog.csdn.net/zhangh8627/article/details/78621275

你可能感兴趣的:(front-end)