angular4基础之路由

来源:互联网 发布:电子秤单片机 编辑:程序博客网 时间:2024/06/01 10:20

路由

  • Routes : 路由配置保存着那个url对应着那个组件,以及在那个routerOutlet中展示的信息
  • RouterOutlet:在HTML中白哦记录有内容呈现位置的指令
  • Router: 负责在运行时执行路由的对象,可以通过调用其navigate()和navigatgeByUrl()方法来到导航到指定路由
  • RouterLink:在HTML中声明路由导航用的指令
  • ActivatedRoute当前激活的路由对象,保存着当前的路由信息,如路由地址,路由参数等
  • 当点击一个导航时,就会按照路由配置,替换该路由配置所对应的插座中的内容.。
    • 路由的寻找路径是从里向外寻找。从小向大。
首先创建一个路由模块
  • 在routes中对路由的匹配是自上而下识别的。通配符的要放在最后
import {NgModule} from "@angular/core";import {Routes, RouterModule} from "@angular/router";import {HomeComponent} from "./home/home.component";const routes: Routes = [//储存的信息  {path: '', component: HomeComponent},  {path: 'product/:id', component: HomeComponent},  {path:'**',component:404Compent}//当找不到要导航的路由时,导航到这个页面,这个放在最下边];@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule],  providers: []})export class AppRoutingModule { }
然后将主模块导入配置好的路由模块:
import { NgModule }       from '@angular/core';import { BrowserModule }  from '@angular/platform-browser';import { FormsModule }    from '@angular/forms';...@NgModule({  imports: [    BrowserModule,    FormsModule,    AppRoutingModule//导入配置好的路由模块  ],  declarations: [    AppComponent,    HomeComponent,    HeroesComponent,    PageNotFoundComponent  ],  bootstrap: [ AppComponent ]})export class AppModule { }
之后在页面中需要一个容器来承载子模块的内容,并导航
  • 在html页面中用routerLink控制导航
<!--HTML页面--> <h1>Angular Router</h1>    <nav>    <!--这里的路由用的是数组,可以传递一些参数-->      <a routerLink="['/']" routerLinkActive="active">Home</a>      <!--routerLink指令就是给a标签添加一个跳转导航。点击之后会导航向对应路由,并获取对应路由的内容,放入下边的容器-->      <!--routerLinkActive定义该路由激活时的样式类。-->      <a routerLink="['/product']" routerLinkActive="active">Heroes</a>    </nav>    <router-outlet></router-outlet><!--承载容器,点击上边两个之后所显示的内容会放在这里-->
  • 在components.ts文件里用router控制路由导航
<!--html文件-->   <!--点击之后调用muroute方法-->    <button (click)="myroute()"></button>    <router-outlet></router-outlet><!--承载容器,点击上边按钮之后所显示的内容会放在这里--><!--components.ts文件-->import { Component } from '@angular/core';import {Router}from"@angular/router";@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css']})export class AppComponent {  title = 'app';constructor(private router:Router){}<!--myroute方法被html页面点击调用-->myroute(){this.router.navigate(['/product']);<!--路由导航-->}}
关于路由附带参数的问题
  • 路由跳转时怎样附带参数
1.<!--在查询参数中传递数据  直接附加在html上的routerlink上边--><a [routerLink]="['/product']" [queryParams]="{id:1}"></a>2.1<!--在路由路径中传递数据  在模块中附加参数,html中直接附加数据-->{ path: 'heroes/:id', component: HeroesComponent }  //模块<a [routerLink]="['/product',1]"></a>  //html  2.2<!--通过点击事件调用方法进行导航-->myroute(){this.router.navigate(['/product,2]);<!--路由导航-->}3.<!--在路由配置中传递数据--><!--很少用-->
  • 当路由附带参数时,怎样接收参数(ActivatedRoute)
import { ActivatedRoute, Params }   from '@angular/router';//引入该模块...private productId:number;   export class a {    constructor(       private route: ActivatedRoute //接收    ) {}    // 路由参数    this.productId=this.route.queryParams[id]; //对应第一个在查询参数中传递数据 /product?id=1&name=2    this.productId=this.route.params[id];//对应第二个在路由路径中传递数据{ path: 'heroes/:id', component: HeroesComponent }}
  • 小问题,当有两个点击导航向同一个路由时,相当于路由没变,所以并不会刷新页面。所以即使两次附加的参数不同,也不会进行改变。
  • 解决办法:为参数进行订阅。
<!--订阅-->this.route.params.subscribe((params:Params)=>this.productId==params["id"]);
重定向路由
import {NgModule} from "@angular/core";import {Routes, RouterModule} from "@angular/router";import {HomeComponent} from "./home/home.component";const routes: Routes = [  //重定向路由  {path: '', redirectTo:'/home',pathMatch:'full'},//当访问空链接时,会跳转向home路由  {path:'home',component: HomeComponent},];@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule],  providers: []})export class AppRoutingModule { }
子路由
  • 在子页面里可以无限嵌套承载容器来跳转子路由
  • 注意: 子路由导航的前提是子页面必须有承载容器,如果没有承载容器,就不会寻找子路由。
  • 导航的子路由路径上必须有父路径的路径及参数
  • 组件并不知道什么是路由,路由的导航完全由配置决定。
import {NgModule} from "@angular/core";import {Routes, RouterModule} from "@angular/router";import {HomeComponent} from "./home/home.component";const routes: Routes = [  {path:'home',component: HomeComponent,  children:[//子路由  {path:'',component: asefComponent},//放在孩子里他就是子路由,放在外边他就是父路由  {path:'/self',component: selfComponent,}  ]},];@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule],  providers: []})export class AppRoutingModule { }
辅助路由
  • 辅助路由就相当于又多了一个路由,这个路由不受其他路由的影响。
  • 对辅助路由进行控制时,也可以同时对主路由进行控制
    • {outlets:{primary:’home’,aux:’chart’}}
    • 因为primary是主路由,aux是辅助路由的名字,所以还可以在后边根据需求无限附加辅助路由进行控制。
<!--HTML--><a [routerLink]="['/product',1]"></a> //主路由<a [routerLink]="['/product']"></a>//主路由<!--当点击开始聊天时,他会时这个辅助路由导航向聊天页面,同时是主路由导航向home页面,当点击结束聊天时,辅助路由为空,所以内容也会消失为空。--><!--{outlets:{aux:''}}这个是辅助路由,aux是辅助路由的名字。可以有多个辅助路由。后边是路径--><!--{outlets:{primary:'home',aux:'chart'}} primary是主路由,在控制辅助路由时也可以控制住路由的导航,根据需求可写可不写--><a [routerLink]="[{outlets:{primary:'home',aux:'chart'}}]">开始聊天</a><a [routerLink]="[{outlets:{aux:''}}]">结束聊天</a><router-outlet></router-outlet><router-outlet name="aux"></router-outlet>//辅助路由<!--路由配置-->const routes: Routes = [  {path:'home',component: HomeComponent},  {path:'chart',component: chartComponent},];
路由守卫
  • 新建一个guard文件来存储各种守卫
  • 在路由模块中为需要进行验证判断的路由添加相应的守卫。并在服务中写入这些守卫。
import {NgModule} from "@angular/core";import {Routes, RouterModule} from "@angular/router";import {HomeComponent} from "./home/home.component";const routes: Routes = [  {path: '', component: HomeComponent},  {path: 'product/:id', component: HomeComponent,  canActivate:[LoginGuard]//为这个路由添加守卫  },];@NgModule({  imports: [RouterModule.forRoot(routes)],  exports: [RouterModule],  providers: [LoginGuard]//在提供中也需要添加守卫名字})export class AppRoutingModule { }
  • 当导航向一个带有守卫的路由时,需要进行守卫验证,当守卫验证通过时,才会正确的进入路由。否则进行守卫中的其他操作。
  • 各种守卫
//验证守卫  CanActivate  判断各种数据是否匹配import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";import {Observable} from "rxjs";/** * Created by zhailiang on 2017/1/23. */export class LoginGuard implements CanActivate {  //导出验证守卫  canActivate(route: ActivatedRouteSnapshot,              state: RouterStateSnapshot):              Observable<boolean>|Promise<boolean>|boolean {    let loggedIn:boolean = Math.random() <0.5;//模拟传入的参数    if(!loggedIn){//根据传入参数判断是否登录      console.log("LoginGuard:用户未登录"+new Date());    }    return loggedIn;//根据不同结果导航进不同界面或给予提示  }}//验证是否保存的守卫  也就是离开这个路由时的验证//CanDeactivate<ProductComponent>这里时传入现在所在的页面组件import {CanDeactivate} from "@angular/router";import {ProductComponent} from "../product/product.component";/** * Created by zhailiang on 2017/1/23. */export class UnsavedGuard implements CanDeactivate<ProductComponent> {//泛型,指定当前组件也就是现在所在的页面组件,为了保护组件 //当离开这个路由时给予下面的提示,如果点击取消则还会保留在本页面。  canDeactivate() {    return window.confirm("你还没有保存.确定要离开么?");  }}//Resolve守卫   也就是当导航向一个路由时,会验证参数,如果匹配则获取这些数据,并导航向正确路由,同时将数据放入页面中,如果不匹配则导航向其他路由。import {Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router";import {ProductComponent, Product} from "../product/product.component";import {Injectable} from "@angular/core";import {Observable} from "rxjs";/** * Created by zhailiang on 2017/1/23. */@Injectable()export class ProductResolveGuard implements Resolve<Product> {// 同样是泛型,这里是要解析出来的数据类型  这个数据类型要进行声明,也就是定义  constructor(private router: Router) {  }  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Product>|Promise<Product>|Product{  //这的route就是productComponent里的this.ActivatedRoute    let productId:number = route.params['id'];//获取路由参数    if(productId == 1) {      return new Product(1,'mignzi');//如果验证通过就从后台获取数据并返回进导航的路由    }else{      this.router.navigate(['/home']);//如果不通过则跳转路由进入首页      return undefined;    }  }}
原创粉丝点击