今天我们要讲的是ng2的路由的第二部分,包括路由嵌套、路由生命周期等知识点。

例子

例子仍然是上节课的例子:

上节课,我们讲解了英雄列表,这节课我们讲解危机中心。

源代码:

https://github.com/lewis617/angular2-tutorial/tree/gh-pages/router

运行方法:

在根目录下运行:

http-server

路由嵌套

我们在app/app.component.ts中定义了路由url和视图组件,其中包括这样一项:

app/app.component.ts

{ // Crisis Center child route
    path: '/crisis-center/...',
    name: 'CrisisCenter',
    component: CrisisCenterComponent,
    useAsDefault: true
  },

那个...就是代表这个url下面可以定义子路由,也就是嵌套路由。嵌套路由是如何实现的?很简单,只需要在视图组件中再次配置路由即可:

app/crisis-center/crisis-center.component.ts

import {Component}     from 'angular2/core';
import {RouteConfig, RouterOutlet} from 'angular2/router';

import {CrisisListComponent}   from './crisis-list.component';
import {CrisisDetailComponent} from './crisis-detail.component';
import {CrisisService}         from './crisis.service';

@Component({
  template:  `
    <h2>CRISIS CENTER</h2>
    <router-outlet></router-outlet>
  `,
  directives: [RouterOutlet],
  providers:  [CrisisService]
})
@RouteConfig([
  {path:'/',    name: 'CrisisList',   component: CrisisListComponent, useAsDefault: true},
  {path:'/:id', name: 'CrisisDetail', component: CrisisDetailComponent}
])
export class CrisisCenterComponent { }

上述代码,我们干了几件事“:

  1. 写了一个组件,包括h2和router-outlet
  2. 使用@RouteConfig,进行路由配置

这样我们就实现了嵌套路由。就是这么简单。

路由生命周期

路由跳转到别的视图的时候,会触发一个路由的生命周期钩子:routerCanDeactivate:

app/crisis-center/crisis-detail.component.ts

routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) : any {
    // Allow synchronous navigation (`true`) if no crisis or the crisis is unchanged.
    if (!this.crisis || this.crisis.name === this.editName) {
      return true;
    }
    // Otherwise ask the user with the dialog service and return its
    // promise which resolves to true or false when the user decides
    return this._dialog.confirm('Discard changes?');
  }

这段代码,会在你修改完危机信息后,既不点击save也不点击cancer时候触发。也就是this._dialog.confirm('Discard changes?');弹出一个对话框:

这里为什么要使用单独的dialog服务呢?为何不直接出发window.confirm()?因为路由的生命周期接受bool或者promise对象(ng1也是这样哦)。而window.confirm并不返回一个promise对象,我们需要对其进行包装:

app/dialog.service.ts

import {Injectable} from 'angular2/core';
/**
 * Async modal dialog service
 * DialogService makes this app easier to test by faking this service.
 * TODO: better modal implemenation that doesn't use window.confirm
 */
@Injectable()
export class DialogService {
  /**
   * Ask user to confirm an action. `message` explains the action and choices.
   * Returns promise resolving to `true`=confirm or `false`=cancel
   */
  confirm(message?:string) {
    return new Promise<boolean>((resolve, reject) =>
      resolve(window.confirm(message || 'Is it OK?')));
  };
}

我们使用promise包装了confirm这个方法,使得这个服务,会触发confirm的同时,最后也能返回一个promise。这样以来我们就可以在路由的生命周期中尽情的使用了!

值得一提的是ng1路由的resolve属性也是接受一个promise,有兴趣的同学可以看我在ng1中对wilddog的路由改装:

https://github.com/lewis617/wild-angular-seed/blob/gh-pages/components/wilddog.utils/wilddog.utils.js#L85

matrix URL notation

当我们从危机详情视图返回危机列表视图的时候,我们发现我们url变成了:http://localhost:63342/angular2-tutorial/router/index.html/crisis-center/;id=1;foo=foo

;id=1;foo=foo这个参数是我们没有见过的,我们知道query string一般都是"?"加"&",而这个参数则使用了";",这叫做matrix URL notation。

Matrix URL notation is an idea first floated in a 1996 proposal by the founder of the web, Tim Berners-Lee.

Although matrix notation never made it into the HTML standard, it is legal and it became popular among browser routing systems as a way to isolate parameters belonging to parent and child routes. The Angular Component Router is such a system.

The syntax may seem strange to us but users are unlikely to notice or care as long as the URL can be emailed and pasted into a browser address bar as this one can.

这是ng2官方文档对这个概念的解释,我们从中得知,这个概念用区分参数属于父视图还是子视图。

我们在上节课英雄列表中,发现url是普通的query string。为什么在这里变成了matrix URL notation?因为英雄列表视图没有子视图,没有嵌套路由的概念。而危机中心则使用了嵌套路由,拥有父子视图的嵌套,为了加一区分,ng2的路由系统使用了matrix URL notation这个概念。


教程源代码及目录

如果您觉得本博客教程帮到了您,就赏颗星吧!

https://github.com/lewis617/angular2-tutorial

angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation的更多相关文章

  1. Vue.js 系列教程 3:Vue-cli,生命周期钩子

    原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...

  2. Windows 8 动手实验系列教程 实验5:进程生命周期管理

    动手实验 实验5:进程生命周期管理 2012年9月 简介 进程生命周期管理对构建Windows应用商店应用的开发者来说是需要理解的最重要的概念之一.不同于传统的Windows应用(它们即使在后台仍然继 ...

  3. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  4. CRL快速开发框架系列教程十一(大数据分库分表解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. angular2系列教程(一)hello world

    今天我们要讲的是angular2系列教程的第一篇,主要是学习angular2的运行,以及感受angular2的components以及模板语法. 例子 这个例子非常简单,是个双向数据绑定.我使用了官网 ...

  6. webpack4 系列教程(十一):字体文件处理

    教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十一):字体文件处理>原文地址.或者来我的小站看更多内容:godbmw.com 0. 课程介 ...

  7. iOS系列 基础篇 03 探究应用生命周期

    iOS系列 基础篇 03 探究应用生命周期 目录: 1. 非运行状态 - 应用启动场景 2. 点击Home键 - 应用退出场景 3. 挂起重新运行场景 4. 内存清除 - 应用终止场景 5. 结尾 本 ...

  8. iOS系列 基础篇 04 探究视图生命周期

    iOS系列 基础篇 04 探究视图生命周期 视图是应用的一个重要的组成部份,功能的实现与其息息相关,而视图控制器控制着视图,其重要性在整个应用中不言而喻. 以视图的四种状态为基础,我们来系统了解一下视 ...

  9. angular2系列教程(五)Structural directives、再谈组件生命周期

    今天,我们要讲的是structural directives和组件生命周期这两个知识点.structural directives顾名思义就是改变dom结构的指令.著名的内建结构指令有 ngIf, n ...

随机推荐

  1. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  2. 实例操作JSONP原理

    絮语:按这个步骤走,你就会明白JSONP是什么鬼. 1.工程目录: ng-mywork demo.html test.js 2.nginx的server配置 server { listen ; ser ...

  3. MJRefresh 源码解读 + 使用

    MJRefresh这个刷新控件是一款非常好用的框架,我们在使用一个框架的同时,最好能了解下它的实现原理,不管是根据业务要求在原有的基础上修改代码,还是其他的目的,弄明白作者的思路和代码风格,会受益匪浅 ...

  4. JQuery(2)

    JQuery下拉框操作: 取值赋值操作 body代码: <select id="sel"> <option value="北京">北京& ...

  5. RabbitMQ + PHP (三)案例演示

    今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...

  6. 升级npm

    查看npm的所有版本 运行命令: npm view npm versions 命令运行后,会输出到目前为止npm的所有版本. [ '1.1.25', '1.1.70', '1.1.71', '1.2. ...

  7. ie6 ie7 ie8 ie9兼容问题终极解决方案

    放下包袱,解决低版本兼容问题   这是一个老生常谈的问题,自然解决这个问题的方案也比较多,下面整理了一些解决方法: 1.强制使用高版本渲染模式. 强制使用Edge模式来解析网页代码 <meta ...

  8. Atitit  godaddy 文件权限 root权限设置

    Atitit  godaddy 文件权限 root权限设置 1. ubuntu需要先登录,再su切换到root1 2. sudo 授权许可使用的su,也是受限制的su1 3. ubuntu默认吗roo ...

  9. 如何区别char与varchar?

    1.varchar与char两个数据类型用于存储字符串长度小于255的字符,MySQL5.0之前是varchar支持最大255.比如向一个长度为40个字符的字段中输入一个为10个字符的数据.使用var ...

  10. DB2重启数据库实例

    DB2重启数据库实例时,有时停止实例会失败,此时需要先确认没有应用链接数据库,然后再关闭数据库实例,并重新启动. 1.查看是否有活动的链接 命令:db2 list applications for d ...