Angular 2 之一 系统架构
Angular 2系统架构中组件是最核心的概念,组件由元数据(Metadata)、组件类(Component)和模板(Template)组成,其中:
- 元数据描述组件的属性
- 组件类实现组件的功能,可调用依赖注入(Dependent Injection)的服务(Service)
- 模板定义组件的视图(View),其中包括HTML元素(element)、其他组件和/或Directive。
组件类和模板通过数据绑定关联:通过属性绑定(Perperty Binding)在模板视图中显示属性值,用户操作模板视图触发事件通过事件绑定(Event Binding)回调组件的事件处理函数。 注意:系统架构仅包括Angular 2核心,可选的路由、HTTP服务未包括在内。
组件 Component
@Component({ selector: "increase", template: ` <div class="myborder"> <div>数值是: {{value}}</div> </div>`, providers: [ CalcService ], directives: [], pipes: [], styles: [ ".myborder { border: 1px solid; }" ] }) export class Increase { ... }
其中:
- selector:CSS selector,对组件一般是元素名称
- template:组件视图模板
- providers:组件级依赖注入的服务列表
- directives:模板可使用的其他组件和Directive
- 模板可使用的Pipe列表
- 本组件使用的CSS样式表。
组件类class定义组件组件功能,如:
export class Increase { @Input() value: number; @Output() changed: EventEmitter<string> = new EventEmitter(); constructor(private calc: CalcService) { } private onIncrease(event: any) { this.value = this.calc.increase(this.value); this.changed.next(`数值增加到${this.value}`); } }
其中:
- @Input声明输入的属性绑定成员字段
- @Output声明输出的事件绑定成员字段
- 构造函数通过参数类型CalcService自动注入服务实例,并由TypeScript自动赋值给私有的this.calc成员字段
- 在事件绑定的处理函数中,可以调用依赖注入的服务,并更新成员变量值。成员变量值更新后,由Angular 2的变更检测自动更新到视图中
- this.changed.next ()向父组件输出事件,事件参数是字符串。
元数据 Metadata
元数据告诉Angular 2如何处理类。如@Component是采用TypeScript标注( decorator)方式表示的组件配置信息。TypeScript标注是一个函数,将组件配置信息转换为附加在类定义上的元数据,Angular 2在运行时根据元数据创建和显示组件实例。
其他常用的元数据包括@Injectable、@Input、@Output、@RouteConfig等。
数据绑定 Data Binding
应用程序需要在DOM中显示内容,也需要响应用户操作。Angular 2通过以下四种数据绑定机制关联组件模板和组件类:
- 在DOM中显示表达式的值
- 通过属性绑定输入参数,在DOM中显示
- 通过事件绑定处理逻辑,由DOM事件触发
- 双向绑定,一般用于表单。
依赖注入 Dependency Injection
Angular 2使用依赖注入向类注入服务实例,以及服务实例所有的依赖实例。Angular 2采用构造注入,一般地根据构造函数的参数类型确定注入实例。
Angular 2可以在bootstrap函数注册全局provider,或者在组件定义时注册组件级provider。如下图所示,注册之后在创建组件时能通过Injector获取对应的服务实例。
Directive
Angular 2模板根据directive指令动态生成DOM。
Directive是使用@Directive标注的类,分为结构型(structural)和属性型(attribute)。系统预定义的结构型Directive包括ngIf、ngFor和ngSwitch,属性型Directive包括ngClass、ngStyle等。Directive可以自定义。
服务 Service
Angular 2对服务没有特殊定义;一般地,任何独立的功能均可定义为服务。
服务主要被组件调用,组件通过依赖注入使用服务。一个定义良好的组件一般地仅处理输入属性和事件回调,其他功能均可封装为服务。