Angular 2.0版本内容

Angular2框架,提供了以下几个基本的功能:

  • 模块
  • 组件
  • 服务
  • 模板
  • 数据绑定
  • 依赖注入

模块是一个业务功能的集合,我们可以把几个组件、服务和其他一些业务模型的定义都加到一个模块里,他的功能更多的是帮助我们更好的组织我们的代码,方便代码重用。模板、数据绑定、依赖注入是定义一套这个框架的规则和语法,我们用这套规则和语法编写的代码,就能够享受Angular2给我们带来的便利。

模块

Angular2的模块可以将组件、服务、指令、方法等封装成一个模块,如下图所示(图片摘自官网):
library-module.png

比如我们开发一个系统,里面包含一个”我的消息”的功能,这个功能包含一些组件,如消息列表、详细详情、回复、新消息和好友列表等。除了这些组件,我们又需要相应的服务来跟服务器交互来提供数据。

在Angular2中,提供了很多模块,例如上面的FormsModuleCommonModule, 还有Router等。他们都是一个个模块,也算是库,可以单独引入使用,也可以只引入需要的部分。

组件和指令

Angular2的组件是一个可重用的单元,包含模版、样式,还有数据、事件等交互逻辑。

每个组件(除了根组件)都会有一个父组件,每个组件定义中的selector的值,对应父组件中的一个html标签。

元数据

元数据就是在定义模块、组件、服务的时候,Decorator方法里面的参数内容,例如一个AppComponent的元数据,就是@Component里面的参数,如下:

{    selector: 'root-app',  
  templateUrl: 'app/app.component.html', 
  styleUrls: ['app/app.component.css']
}

服务

在Angular2中,服务是一个很宽泛的定义,任何的类都可以被定义成服务,这个类中可以包含一些业务方法,可以包含环境配置变量。Angular2也没有对服务的定义做任何的规则限制。我们只需要定义一个class,并把它export就可以。但是,一般我们都是结合依赖注入来使用服务。

依赖注入

从Angular1的版本开始,依赖注入就是一个很核心的概念,在版本2中,主要是用于管理service实例的注入。在上面讲的service中,我们创建了一个SomeService,在传统的用法中,我们都是在需要用他的地方手动创建一个这个类的实例,然后调用他的相应方法或属性,

但是,当我们的系统中有很多service类,甚至这些service类相互之间又需要引用的时候,我们就没有办法都通过手动创建的方式来获取service实例。更重要的是,这对于系统的解耦非常不便,不同的服务之间直接创建和引用,会让系统变得非常难以维护。
Angular给我们提供了一个非常好的解决方案,它借用了java等语言中某些容器库的概念,将所有service实例的创建都由容器来完成,当一个service需要引用另一个service的时候,不是自己创建另一个service的实例,而是从容器中获取那个service的实例。

有关依赖注入,需要注意的一点就是依赖注入的作用范围。Angular2的依赖注入是一个树形的结构,就好像组件树一样

数据绑定

在JQuery或者更早的时代,当我们需要更新页面的内容的时候,我们一般都需要自己获得页面的DOM,然后,设置他的值。当页面上的内容需要更新到js端的时候,又需要设置一些事件,如onclick, onblur等,然后在响应事件里面再从页面获得这个值。这不仅需要些很多代码、浪费时间,还非常容易出错。终于,Angular把我们从这些枯燥的工作中解放出来,提供了数据绑定的功能。
在Angular1.x的版本中,数据绑定是通过轮询实现的。在Angular1里,所有需要绑定的数据都会在$scope中,Angular1.x有一个轮训机制,每隔一段时间就检查所有绑定的变量,检查他们现在的值跟上次检查的值是否一致,如果不一致,就触发相应的方法更新页面的内容。这虽然给我们开发带来了便利,但是如果有太多的变量需要监听,就会造成很大的性能问题。
在Angular2里面,绑定的数据的监听是通过zone.js实现。通俗来讲,zone给所有有可能更新数据的方法加了一个补丁,就像AOP,或者说代理模式。每当这些更新数据的方法被调用的时候,就会触发另一个方法,告诉Angular有数据修改,Angular再去判断变量是否修改,如果有修改,就更新DOM。
而且,Angular2的数据更新检测是在每个组件上有一个检测器。这样,就算应用中有再多绑定的变量,当有一个数据修改的事件以后,也只是对应的那个组件的检测器被触发,来检查它以及它所有的子组件的数据修改。
这两方面结合,就使得Angular2应用的性能能够有很大的提升。

官方图:

databinding.png

它们之间的关系

为了描述这几个功能之间的关系,官方图:
overview2-basic.png

这张图就比较清楚的说明了组件、服务、模板、Directive(指令)、数据绑定和依赖注入的相互关系。结合这张图和上面说的开发一个Angular2的应用的基本过程,这样就更容易理解了。
下面,我们来看一下Angular应用的工作流程。

  1. 我们定义一个根模块和一个根组件,然后在main.ts里面用这个根模块启动应用。
  2. 根组件里面的一个html标签如果匹配了某一个组件的’selector’,这个组件就会被加载在这个标签里面。这样,整个应用就是一个组件树,
  3. 我们定义的Component信息,也就是类和Metadata(元数据),Angular会根据这个组件定义将组件中定义的模板显示到selector对应的标签上,将样式应用到模板页面上。组件和模板之间又通过数据绑定联系起来,组件中的变量通过数据绑定展示到模板上,模板又通过事件绑定,对应到组件里的方法上。Directive的工作原理也跟上面类似。
  4. 最后,我们定义的service被Angular的Injector保存在一个树形结构的容器里,在某个组件中当我们需要使用这个service时,就可以在构造函数中直接获得这个service的实例,而不用手动创建。这样,多个组件,或者模块都可以共用一个service的实例。所以,service除了提供业务方法,也能提供共享数据、数据传输等功能。

其它版本:

angular 2.0版本内容