Angular 2 之四 组件(续)
为了将Angular 2组件显示在DOM树中,组件必须和一个DOM元素关联,该DOM元素称为宿主元素。 组件可以和宿主元素进行以下交互:
- 监听宿主元素的事件
- 更改宿主元素的属性
- 调用宿主元素的方法。
@HostBinding标注用于将宿主元素的属性和组件属性绑定,@HostListener标注用于当宿主元素输出某种事件时调用组件成员方法。
宿主元素的概念也能应用在Directive。
组件交互 Component Interaction
组件交互指组件和组件之间交互信息的方式,其中属性绑定和事件绑定是父子组件间最常见的交互方式。
1. @Input属性绑定
属性绑定用于父组件向子组件传递数据。子组件可以采用以下两种方式获取属性的变更:
- 属性set方法
- ngOnChange回调。
2. @Output事件绑定
事件绑定用于子组件向父组件触发事件,父组件通过绑定的处理函数处理事件。
3. 模板局部变量
父组件在模板中采用模板局部变量访问子组件属性或方法。
4. @ViewChild和@ViewContent
父组件通过@ViewChild或者@ViewChildren标记访问模板中的子组件。父组件通过@ContentChild或者@ContentChildren标记访问元素内容中 的子组件。
5. 通过服务交互
如果需交互的组件间没有父子层级关系,则可以通过注入同一服务实例,通过服务实现信息交互。注意,由于注入层级问题,该服务实例必须至少注入在共同祖先之上。
变更检测 Change Detection
1. 概述
变更检测检测组件状态和上次检测时是否相同,如果有变化就更新对应的视图。 Angular 2变更检测基于zone.js,zone.js能检测和度量异步操作的情况。Angular 2在每次异步操作完成后触发变更检测流程,变更检测采用下述不同策略。
2. 缺省策略
Angular 2应用是一颗组件树,每个组件由所属变更检测器负责检测模板中的数据。变更检测从根组件开始,以深度优先方式遍历组件树。
Angular 2缺省的变更检测策略是检测组件树的每一个节点。由于变更检测发生在每一次浏览器事件后(如鼠标移动),该策略似乎非常低效,然而Angular 2能在几毫秒内完成几十万次检测操作。
3. OnPush策略
如果组件仅依赖于输入属性,且输入属性是不可变的(immutable),那么组件子树当且仅当输入属性有变化时才需要更新。
如果组件满足上述条件,在组件定义时增加以下元数据指定采用OnPush检测策略:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush
});
保证数据不可变性的库参见Immutable.js。
假设整颗组件树均采用OnPush策略,Angular 2仍需要从根组件开始以深度优先顺序依次检测所有节点,其算法复杂度是O(N)。
4. Observable
如果组件仅依赖于输入属性,且输入属性是Observable,那么组件子树当且仅当输入属性输出事件时才需要更新。
输入属性字段声明为Observable使用该策略,例如:todos : Observable<array>;
假设整颗组件树均采用Observable策略,Angular 2仅需检测根组件到变更组件路径上的组件集合,其算法复杂度是O(logN)。
生命周期 Life Cycle
组件生命周期的回调函数按以下顺序被回调:
- ngOnChanges: @Input输入属性有变化时。注意,还可以通过set方法获取变化的属性值
- ngOnInit: 第一次ngOnChanges之后。注意,组件的构造函数中@Input属性尚未设置
- ngDoCheck: 每次变更检测时
- ngAfterContentInit: ng-content中子组件已初始化,通过@ContentChild和@ContentChildren声明的成员变量可用
- ngAfterContentChecked: 每次Content中的子组件变更检测时
- ngAfterViewInit: 模板中的子组件已初始化,通过@ViewChild和@ViewChildren声明的成员变量可用
- ngAfterViewChecked: 每次模板中的子组件变更检测时
- ngOnDestroy: 组件销毁前调用
View Encapsulation
Shadow DOM是一种Web Component规范,目前仅Chrome和Opera浏览器支持。
Angular 2通过元数据设置组件是否使用浏览器内置Shadow DOM,元数据encapsulation取值如下:
- ViewEncapsulation.None: 不使用Shadow DOM
- ViewEncapsulation.Emulated: 模拟实现Shadow DOM,该值为缺省值
- ViewEncapsulation.Native: 使用浏览器内置的Shadow DOM实现。