今天我们要讲的是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. ASP.NET Core 折腾笔记一

    前言: 在ASP.NET Core 1.0时,曾折腾过一次,后因发现不了System.Data而停止. 更因VS2015提示过期Delete掉VS了,其实主要还是笔记本的硬盘空间吃紧. 快双十一了,本 ...

  2. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  3. javascript之活灵活现的Array

    前言 就如同标题一样,这篇文章将会灵活的运行Array对象的一些方法来实现看上去较复杂的应用. 大家都知道Array实例有这四个方法:push.pop.shift.unshift.大家也都知道 pus ...

  4. 在centos7中添加一个新用户,并授权

    前言 笔记本装了一个centos,想要让别人也可以登录访问,用自己的账号确实不太好,于是准备新建一个用户给他. 创建新用户 创建一个用户名为:zhangbiao [root@localhost ~]# ...

  5. 代码的坏味道(21)——中间人(Middle Man)

    坏味道--中间人(Middle Man) 特征 如果一个类的作用仅仅是指向另一个类的委托,为什么要存在呢? 问题原因 对象的基本特征之一就是封装:对外部世界隐藏其内部细节.封装往往伴随委托.但是人们可 ...

  6. IL异常处理

    异常处理在程序中也算是比较重要的一部分了,IL异常处理在C#里面实现会用到一些新的方法 1.BeginExceptionBlock:异常块代码开始,相当于try,但是感觉又不太像 2.EndExcep ...

  7. 彻底搞懂Javascript的“==”

    本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...

  8. ES6之变量常量字符串数值

    ECMAScript 6 是 JavaScript 语言的最新一代标准,当前标准已于 2015 年 6 月正式发布,故又称 ECMAScript 2015. ES6对数据类型进行了一些扩展 在js中使 ...

  9. svn常用命令

    1.新建版本库 [root@localhost repos]# mkdir -p project [root@localhost repos]# svnadmin create project [ro ...

  10. 清除打印机队列中无法清除的任务 & 清空打印池

    故障现象典型表现为以下两种情况 1.当打印任务开始进行时,这些打印任务便被保存在打印作业列表(也称打印队列)内.如果打印机因意外暂停(如打印机未连接)而未完成打印任务,则该打印任务将列入打印队列,并且 ...