angular2架构总览

核心模块

一个完整的angular应用主要由6个部分构成,分别是:组件、模板、指令、服务、依赖注入和路由。
与用户直接交互的是模板视图.

组件

angular框架基于组件设计。
树状结构的组件关系意味着每个组件并不是孤立的存在,父子组件之间存在着双向的数据流动。要理解数据是怎样流动的,首先要了解组件间调用方式。简单说,组件的外在形式就是自定义标签,所以组件的调用实际体现在模板标签里的引用。Contact组件代码:

@Component({
    selector:'contact',
    template:'
xxxx
' }) export class ContactComponent { @Input() item:ContactModel; @Output() update:EventEmitter; constructor() {} //... }

@Input()和@Output()声明了组件Contact对外暴露的接口,item变量用来接收来自父组件的数据源输入,update接口用于向父组件发送数据。
ContactList父组件代码:

@Component({
    selector:'contact-list',
    template:`
        
        
    `
})
export class ContactListComponent {
    listItem:ContactModel[];
    constructor() {}
    doUpdate(item:ContactModel) {
        //...
    }
}

由template属性值可见,父子组件之间通过类似于HTML属性的方式传递数据,其中[item]称为属性绑定,数据从父组件流向子组件;(update)称为事件绑定,数据从子组件流向父组件。
angular的模版里可以直接引用组件的成员属性,如listItem和doUpdate。组件类和模版之间的数据交互称为数据绑定,属性绑定和事件绑定也属于数据绑定,既可用于父子组件的数据传递,也可用于组件数据模型和模版视图之间的数据传递。所以在父子组件通信的过程中,模版充当桥梁的角色。
angular的数据流动机制如下图:

数据流动并不是自发形成的,流动需要一个驱动力,这个驱动力即angular的变化检测机制。angular以适当的时机去检验对象的值是否被改动过,这个时机通常是在用户操作事件(如点击),setTimeout或XHR回调等这些异步事件触发之后。angular捕获这些异步事件的工作是通过Zones库实现的。
每个组件背后都维护着一个独立的变化监测器,这个变化监测器记录着所属组件的数据变更状态。由于应用是以组件数的形式组织,因此每个应用也有着对应的一颗变化检测树。当Zones捕获到某异步事件后,它都会通知angular执行变化检测操作,每次变化检测操作都始于根组件,并以深度优先的原则向叶子组件遍历执行。

模版

angular模版基于HTML,普通的HTML亦可作为模板输入。
数据绑定是模板最基本的功能,除了属性绑定和事件绑定,插值也是常见的数据绑定语法。

@Component({
    selector:'contact',
    template:`
        
{{item.name}}
` })

插值语法是由{{}}组成,插值的变量上下文是组件类本身,插值是一种单向的数据流动,从数据模型到模板视图。
属性绑定、事件绑定和插值的数据流动都是单向的,双向数据绑定需结合属性绑定和事件绑定。


数据绑定负责数据的传递与展示,而数据的格式化显示是通过管道功能实现的。

{{contact.name|phone}}

指令

组件也是指令的一种。组件与一般指令的区别:组件带有单独的模版,而一般的指令作用在已有的DOM元素上。一般的指令分为两种:结构指令和属性指令。
结构指令能够添加、修改或删除DOM。


属性指令用来改变元素的外观或行为。

{{contact.name}}

setStyles()是其组件类的成员函数,返回一个计算好的样式对象。

class ContactComponent {
    private isImportant:boolean;
    setStyles() {
        return {
            'font-size':'14px',
            'font-weight':this.isImportant?'bold':'normal'
        }
    }
}

服务

服务是封装单一功能的单元,类似于工具库,常被引用于组件内部,作为组件的功能扩展。

依赖注入

通过依赖注入机制,服务等模块可以被引入到任何一个组件(或模块,或其他服务)中。

import { LoggerService } from './logger-service';
@Component({
    selector:'contact-list',
    providers:[LoggerService]
})
export class ContactListComponent{
    constructor(private logger:LoggerService){}
    doSomething(){
        this.logger.info('xxx');
    }
}

@Component装饰器中的providers属性会为该组件创建一个注入器对象,并新建LoggerService实例存储到这个注入器里。组件在需要引入LoggerService实例时,通过TypeScript的类型匹配即可从注入器取出相应的实例对象,无须再重复显式实例化。
服务的每一次注入(也就是使用providers声明),该服务都会被创建出新的实例,组件的所有子组件均默认继承父组件的注入器对象,复用该注入器里存储的服务实例。这种机制可保证服务以单例模式运行,除非某个子组件再次注入。

路由

路由的作用是建立URL路径和组件之间的对应关系,根据不同URL路径匹配出相应的组件并渲染。

应用模块

每个angualr应用至少有一个模块,一般需要有一个模块作为应用的入口,这个入口模块称为根模块,通过引导运行根模块来启动angular应用。除了根模块其他的模块类型有:封装某个完整功能的特性模块,封装一些公共构件的共享模块,以及存放应用级别核心构件的核心模块。
通过将特性模块导入到根模块里即可实现对该特性功能的引入,模块间的交互关系对于不同的模块构件各不相同。

  • 路由:当特性模块导入到根模块后,特性模块的路由配置会自动与根模块里的路由配置合并。
  • 组件和指令:默认情况下模块内的组件和指令是私有的,除非显式的暴露出某些组件或指令。
  • 服务:注入到组件里的服务只能使用在该组件及其子组件上,而注入到模块里的服务在整个应用里均能使用,因为所有模块都共享着同一个应用级别的根注入器。

angular已经封装了不少常用的特性模块:

  • ApplicationModule:封装一些启动相关的工具
  • CommonModule:封装一些常用的内置指令和内置管道等
  • BrowserModule:封装在浏览器平台运行时的一些工具库,同时将CommonModule和ApplicationModule打包导出,所以通常在使用时引入BrowserModule就可以了
  • FormsModule和ReactiveFormsModule:封装表单相关的组件指令等
  • RouterModule:封装路由相关的组件指令等
  • HttpModule:封装网络请求相关的服务等

angular通过引导运行根模块来启动应用,引导的方式有两种:动态引导和静态引导。
两者的区别就在编译的时机不同,动态引导是将所有代码加载到浏览器后,在浏览器进行编译;静态引导是将编译过程前置到开发时的工程打包阶段,加载到浏览器的将是编译后的代码。
假设根模块为AppModule,动态引导代码:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }  from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

动态引导是从platformBrowserDynamic函数启动,该函数从@angular/platform-browser-dynamic文件模块中导入。
静态引导代码:

import { platformBrowser } from '@angular/platform-browser';
import { AppModule }  from './app.module';
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

静态引导启动的是AppModuleNgFactory模块,这是AppModule经过编译处理后生成的模块(app.module文件编译后生成app.module.ngfactory文件)。由于整个应用已经被预先编译,所以编译器并不会打包到项目代码,代码包体积更小,加载更快,而且也省去了浏览器编译这个步骤,因此应用启动的速度也快。

angular一级模块

  • @angular/core:存放核心代码,如变化监测机制、依赖注入机制、渲染等,核心功能的实现、装饰器(@Component、@Directive等)也会存放到这个模块。
  • @angular/common:存放一些常用的内置指令和内置管道等。
  • @angular/forms:存放表单相关的内置组件及内置指令等。
  • @angular/http:存放网络请求相关的服务等。
  • @angular/router:存放路由相关的组件和指令等。
  • @angular/platform-:存放的是引导启动相关的工具。angular支持在多个平台下运行,不同的平台都有对应的启动工具,这些启动工具会被封装到不同的模块里,如浏览器的启动工具存放在@angular/platform-browser下,服务端渲染的启动工具存放在@angular/platform-server下。

你可能感兴趣的:(angular2架构总览)