从 Angular 1 升级到 Angular 2 需要准备的步骤

我最近在试玩 Angular 2。刚开始感觉很奇怪,和我们钟爱的第 1 版完全不同。第 1 版是用 ES5 标准的纯 javascript 编写,而第 2 版采用了 typescript 和 es 2015。不过,你已经可以采取一些步骤,让你的 Angular 1 代码(或用 Angular 1 创建的新项目)更加接近 Angular 2。

我为什么要为 Angular 1 迁移到 Angular 2 做准备

首先,当时机成熟了,你打算用 Angular 2 作为框架时,肯定想让代码迁移更容易些。目前,Angular 小组已经提供了一些迁移策略,你可以混合使用 Angular 1 和 Angular 2 组件,但目标是要将代码库统一,最终只使用一个框架。

其次,在 Angular 2 中更多的是写纯 javascript,然后才是使用专有的框架代码。

再次,社区和浏览器厂商将逐步拥抱 Ecmascript 的最新标准,所以,坚持使用标准编码,尽可能让代码库可复用,而不管选择的框架是什么。

迁移到 Angular 2 的步骤

采取这些策略可以让你的代码更加接近 Angular 2,使转换变得容易。

1. 开始用 Ecmascript 2015

Angular 2 使用 Typescript 编写,Typescript 是 Ecmascript 2015 的超集,带有更多的特性。不过,如果你不喜欢 Typescript, 也可以只用 Ecmascript 2015 编写 angular 2。 目前,代码最终都会编译成 Ecmascript 5。所以实际上你也可以用 Ecmascript 5 来编写 Angular 2。

但是,在我看来,使用 Ecmascript 2015 的新特性,可以减少代码量(有些时候…)、增强代码可读性、用上令人兴奋的特性,如解构。

如果想使用 Ecmascript 2015 的特性,你需要一个转换器来编译代码。目前最流行的转换器是 babel。babel 在很多流行的构建脚本中都可以配置,如 gulp、webpack、browserify 及其它。

2. 使用 “angular.service” 替换 “angular.factory”

使用 Ecmascript 2015 意味着我们可以用新的 “class” 关键字来创建新对象甚至扩展其它对象。我曾经写过,比起继承我更热衷于组合,所以我看不出用 “extend” 实现继承有什么用处,不过通过 class 的特性的确可以为创建对象增加好用的语法糖(简化代码)。

在 angular 1 中的 “service” 和 “factory” 的区别是实例化方法:

“service” 使用 “new” 关键字调用(仅一次)

“factory” 使用普通函数调用 — 不需要 “new” 关键字。

在 Angular 2 中,Services 使用了 Ecmascript 2015 类编写。这会导致你需要将 Angular 1 代码中的 factories 转化成 services,并且使用 “class” 替代 function。

例如在我的开源项目-Echoes Player 中,我使用了“class” 和 Angular“service” 编写 youtube api 服务(我以前用的是 factory):

3. 编写 Controllers 时使用 “Class” 替换 “function”

这一步和上一步多少有些相似。Angular 1 中的 Controllers 总是不停被重建(或 “新建”)- 因为它们不是单例。

Angular 2 几乎不用 controllers。

反之,Angular 2 是基于组件的。每个组件都有一个简单的类(包含少量 es7 注解)来控制。如果你的 Angular 1 代码是用 web 组件方式来编写的,那么很可能每个指令(directive)都对应一个 controller 函数来控制。

有个很重的点必须意识到 - 指令的概念在 Angular 2 中更加简单:

  1. 使用了元素选择器的指令都是组件。
  2. 剩下的都是指令。

Angular 2 仍然会在内部初始化 services 和 controllers,不要自己去初始化,因为那样会导致代码很难测试。不过 Angular 2 还是易于测试并对 TDD (测试驱动开发) 和 BDD(行为驱动开发)友好。我还写过一篇文章,内容是讲为什么应当封装 “new” 关键字,从而写出更容易测试的代码。

例如把 controller 写成类,会使代码迁移到 angular 2 组件变得非常容易:

4. 使用指令封装代码

在这一步,你需要重新思考代码,并且使用更好的架构。从 组件(components)/指令(directives) 的角度开始思考。千万不要在 index.html 或任何未关联指令的模板中编写任何 Angular 代码。例如:如果你在一段描述个人资料卡片的代码中使用了 ng-repeat, 你可以创建一个指令,“<person-profile-card>” 或者 “<profile-cards>” (作为一个列表)。

在即将推出的 Angular 1.5 版本里,你可以使用 ”angular.component“ 定义来创建组件,使得语法( 出自 todd motto 之手)比指令(directive) 更优美。

记住,组件搭配组件(或指令) 就是 Angular 2 的全部,从这个角度思考,将有助于你更好的重新组织代码,也更容易使用 Angular 2。

5. 使用 Angular2to1,ng-upgrade 或其它方法

Angular 2 采用了一个简单漂亮的语法来定义组件(指令)。为了在 es5 代码中体验 Angular 2 的组件语法,我创建了一个 npm 模块 “angular2to1”。示例,你可以在 Angular 1 应用中使用 Angular 2 的 es5 标准语法来定义一个指令:

这和定义一个 Angular 1 指令等效:

有大量的选项可供使用。

ng-upgraders 是一个代码仓库,包含了 Angular 2 升级策略的资源链接。里面有一些有趣的项目,有的项目提供了在 Angular 1 中使用 Angular 2 的 typescript 注解及 Ecmascript 2015 的可能性,这样几乎可以完全用 Angular 2 的语法来写 Angular 1 了。

另外,有很多在 Angular 1 中使用 Ecmascript 2015 的解决方案,无论是从软件架构还是 Angular 推荐架构的角度来看,都坚持了最佳实践和严格准则。

我比较喜欢的一个项目是: NG6-Starter , 项目包含使用 Ecmascrpipt 2015 编写 Angular 1 应用的骨架代码,组件生成器,测试配置和更多内容。

6. (彩蛋)使用模块加载器 system.js、webpack、browserify 或其它工具

所有 Angular 2 例子都依赖于 System.js 库的组件懒加载机制。System.js 既允许我们使用懒加载,也可以编译成压缩好的单一文件用于生产环境。这样你就可以在不同的文件中编写组件(components)和服务(services),不管构建还是开发,都使用构建脚本来解决依赖关系。

In addition, if you rather use gulp.js, webpack or browserify – that’s a no brainer and can be easily configured and integrated.

另外,如果你就是喜欢用 gulp.js、webpack 或 browserify - 完全没理由。没关系,配置和移植都很简单。

总结

我倾向于遵守标准。我认为 Ecmascript 2015 最终会成为了 javascript 语言下一代正式标准,所以,有理由去使用它(我之前也写过)并且拥抱变化。

如果其它的框架、平台和库拥抱了 Ecmascript 2015 标准 ,所有人都会受益。大家可以用更灵活的方式编码,同时在不同的库和项目中共享代码。

1 1 收藏 评论

关于作者:段昕理

因为iPod而喜欢上苹果的一系列产品,非常认同他们追求极致的精神。工作之余,喜欢前端的开源项目,Github(https://github.com/sandywalker) 个人主页 · 我的文章 · 15 ·    

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部