第六章 Http
除非只是一个Demo,否则你的Angular程序总要和后端数据打交道,这个时候就离不开Http模块了。 本章主要是通过一些相对简单的例子来介绍Angular Http模块的使用,包括:
(1)如何注入HttpModule
(2)编写最基本的http request,请求一个网址,并获得JSON响应数据
(3)编写高级一些的带参数的 http 请求,但是要注意 ⚠️ 的是该例子访问的是youtube的API,所以你要想获得code example里的响应数据就得搭梯子。
(4)用RxJS处理返回数据(response)。
如果没有接触过RxJS,对于Observable(可观察对象) 这样的写法可能会感到不适应,不过也没有太大关系,本书作者非常体贴的拿出了两个章节的篇幅来介绍“可观察对象”架构,更深入的资料可以参考RxJS文档(⚠️ 要看rxjs 5.x的),还有中文参考。
第七章 路由
如果是了解Angular.JS 1.x 的朋友会熟悉基于锚点标记的路由(hash-based routing)方式,例如 http://domain.com/#/login
在Angular 2/4 当中,这种方式依然是得到支持的,但是官方文档里强烈建议我们采用HTML5路由模式,即更加自然的路由:
http://domain.com/login
本章对于两种实现方式都给出了例子,那么——
哪种策略更好?
我们必须选择一种策略,并且在项目的早期就这么干。一旦该应用进入了生产阶段,要改起来可就不容易了,因为外面已经有了大量对应用URL的引用。
目前看来,几乎所有的Angular项目都会使用默认的HTML 5风格。它生成的URL更易于被用户理解,它也为将来做服务端渲染预留了空间。
在服务器端渲染指定的页面,是一项可以在该应用首次加载时大幅提升响应速度的技术。那些原本需要十秒甚至更长时间加载的应用,可以预先在服务端渲染好,并在少于一秒的时间内完整呈现在用户的设备上。
只有当应用的URL看起来像是标准的Web URL,中间没有hash(#)时,这个选项才能生效。
除非你有强烈的理由不得不使用锚点标记路由,否则就应该坚决使用默认的HTML 5路由风格。
本章还非常详细的介绍了嵌套路由的开发过程,使得我们能够结合组件(component)开发出具有非常复杂UI的单页面系统,这在angular1.x时是一级很麻烦的事情,然而我们新版的路由系统已经把这件事解决的很好了,甚至为了兼顾路由系统的版本号,把Angular的版本号从2.x直接跳级到4.x,所以大家就放心的用吧。
对于需要更深入了解Angular路由的朋友,建议看看Angular团队重要成员Victor Savkin 的写的Angular路由一书。
图5 Angular Router第八章 依赖注入
依赖注入(Dependency injection)是重要的程序设计模式。 Angular 有一套自己的依赖注入框架,离开了它,你就没法玩 Angular 程序了。 实际上DI在angular.js 1.x的时候被引入的,而且也是ng1.x的最重要特色之一,但是写起来有时候挺麻烦的;而在Angular2/4中,DI的使用就大大的被化简了。
我们可以把注入器看作new操作符的替代品,也就是说,不依赖于使用语言提供的new操作符,依赖注入让我们配置并创建对象。
本章开头以一个PriceService为例,介绍了使用依赖注入的好处:依靠DI我们可以得到一个更加松耦合的架构。这时,当修改某个单一部件(component)时,对程序中其他区域的影响就小多了。同时,只要这些部件之间的接口没有变,我们甚至可以在不修改其他部件中实现代码的情况下集体更换它们。
对于PriceService这个例子,需要指出的是,中文版书中的代码与英文最新版有些差异(英文版中采用了了“价格接口” IPriceService),所以要想更好的理解这个例子请阅读源代码。
图6 依赖注入的组成过程如图6所示:在Angular的DI系统中,我们不是直接导入和创建一个类的新实例,而是通过以下步骤:
(1)注册“依赖关系”
(2)描述如何注入依赖关系
(3)用注入器注入依赖关系
本章后半部分则介绍了如何用NgModule来组织注入依赖,关于NgModule的内容,大家还可以参考Angular中文官网的文档。
第九章 Angular数据架构
实际上这一章是一个Angular高级编程的入口,介绍了Angular数据架构的几种方式,这些不同的方式代表着解决问题的不同思路:
第十、十一章介绍的是官方的可观察者模式(Observable),通过RxJS来实现。
第十二、十三章则介绍的是React上大火的Redux模式。
鉴于本书的这几章写的已经很详细,笔者主要补充一些自己收集到的资料并谈谈看法。
第十、十一章 使用可观察对象的数据架构
如果没有接触过响应式编程(reactive programming),则你可能需要看看一些预备材料,比如《你不容错过的响应式编程入门(中文版)》。
在异步数据处理方式上有很多种方式:回调、Promise、Observable...
Callback对于写JS的人来说都不会陌生,Promise相比Callback在代码可读性和可维护性上都提高了不少,能够避免回调陷阱。
Promise是ng1.x里主要采用的方法,下面谈谈Promise和Observable的区别:
Promise的特点:(1)一次请求返回一个值;(2)不可被撤销。
Observable的特点:(1)随着时间的推移可以使用多个值;(2)可以被撤销;(3)支持map、 filter,、reduce、forEach等操作符。
那么是不是在Angular2/4中就一定要使用Observable呢?
这可不一定,还是要分使用场景的,如果你的数据就是需要发出一次请求获得一个结果,依然可以用Promise,其实我们很多情况下就是这种场景,我们只需要关心这个数据是获取成功还是没有成功就行了。关于这点可以参看这篇文章《Stop using observable when you should use a promise(该用promise的时候就别用observable)》。
大部分时候,使用Promise 是更好地选择,我们通常会用http.get()获取单块数据。只要接收到数据,就算完成。 使用Promise这种形式的结果是让调用方更容易写,并且Promise已经在 JavaScript 程序员中被广泛接受了。
但是请求并非总是“一次性”的。我们可以开始一个请求, 并且取消它,在服务器对第一个请求作出回应之前,再开始另一个不同的请求 。
一个请求-取消-新请求的序列用Promise是很难实现的,但是对Observable来说则很容易。
Observable适合用在数据以Stream(流式数据)出现的实时应用场景,比如聊天室、股票、游戏…… 在这些场景下,数据会从服务端源源不断的推送过来,而用户的响应也随时会改变所需要的数据和数据的展现形式,这个时候Observable的强大功能就发挥出来了。第十章的例子就是一个比较经典的聊天室场景,如果写个支持websocket的服务端,那就是一个聊天室的雏形了;第十一章则是在视图层面,用组件(component)配合聊天数据的展现。
第十二、十三章 Angular 与 Redux
第十二章介绍了怎样用TypeScript来写Redux,并且结合Angular实现了一个迷你计数器。
第十三章则用Redux的方式把第十、十一章的聊天室程序重构了一遍。
Redux的设计思想能在Angular中实现,表明Angular架构具有很大的灵活性,实际上把React.JS和Angular2/4放在一起也没有问题,有兴趣的可以参考ngReact项目。
第十四章 高级组件
组件(component)是Angular2/4的基石,事实上,我们前面的每一个章节都离不开组件,而我们也可以利用Angular提供给我们的API根据需要去构建更加复杂、漂亮、功能更加强大的高级组件,我们甚至可以自定义模版语法,比如像例子中的在“ngIf”的基础上构造出“ngBookIf”语法。
在这个方面 ionic 2/3 可以说是非常经典的例子,这是一套深度实践并封装了Angular 2/4的高级框架,特别适用于移动开发。
Angular Material 项目则是Angular官方支持的以Material风格定义的组件库。
如果要深入学习Angular高级组件开发,还可以参考下面这本书 《Angular 2 Components》
图7 Angular 组件开发第十五章 测试
驱动测试开发(TDD)现在已经是非常主流的开发方式了,而且从产品角度出发,为了提高代码的质量,甚至很多开发者提倡测试要写在开发的前面。
熟悉JS自动测试的朋友一定很熟悉Jasmine和Karma这两个工具。
Angular自身提供了一套基于Jasmine框架的辅助类,位于@angular/core/testing包当中,我们照着书上一步步来就可以比较轻松的学习到Angular的测试流程。
Angular2/4在提供测试功能方面做了大量的工作,使得我们可以轻松地测试应用程序的方方面面:从控制器到服务类、表单和HTTP、异步代码测试等等……。
《Angular Test-Driven Development》此书深入介绍了用TDD的方式开发Angular,指导我们何时,为什么以及如何应用测试技术和最佳实践来创建优质清洁代码。
图8 Angular 驱动测试开发第十六章 从Angular.JS 1.x 升级到 Angular 2/4
如果你已经有Angular.JS 1.x 的项目,需要向Angular 2/4 过渡,没关系,Angular.JS 1.x 和Angular 2/4 的互操作性已经相当完善。
Angular提供了一种方式来启动你的Angular.JS 1.x应用,然后在其中写Angular的组件和服务。写完Angular组件,只要把它和Angular.JS 1.x 组件混在一起就可以了。另外,依赖注入体系也支持在Angular.JS和Angular之间双向传递数据,因此你写的服务在AngularJS和Angular中都能运行。
最后:
由于已经拜读过了ng book 2/4 的英文版,所以此次我对中文版的阅读速度其实是挺快的,在读后感写作过程中也添加了一些我个人收集的一些资料,希望对大家有所帮助。在中文版阅读过程中,我着重注意英文版中一些比较难理解的地方在中文版里的翻译情况,总体而言,我感觉翻译的还是比较流畅自然的,这确实是一本译者们注入了心血的大作,所以在读后感最后再次表示对他们的感谢🙏 ,同时也感谢图灵出了这么一本好书。💻📖
网友评论
10,11,15章写的并不好:
rxjs的基础导入不够, 范例程序也写的特别绕, 边看边想这么用rxjs会不会让看你程序的维护者想拿刀来找你.
Testing这一章的篇幅是可以展开成一本书的, 很多内容并没有交代清楚, 感觉测试几个简单的组件,路由和服务功能实现要做一大堆成本很高的设置工作, 这对TDD的推广并不是什么好事.