Skip to content

Commit 8302aff

Browse files
committed
refactor(LifecycleEvent): remove LifecycleEvent
fixes angular#3924 BREAKING CHANGE The `lifecycle` configuration for directive has been dropped. Before // Dart @component({lifecycle: const [LifecycleEvent.OnChanges], ...}) class MyComponent implements OnChanges { void onChanges() {...} } // Typescript @component({lifecycle: [LifecycleEvent.OnChanges], ...}) class MyComponent implements OnChanges { onChanges(): void {...} } // ES5 var MyComponent = ng. Component({lifecycle: [LifecycleEvent.OnChanges], ...}). Class({ onChanges: function() {...} }); After // Dart @component({...}) class MyComponent implements OnChanges { void onChanges() {...} } // Typescript @component({...}) class MyComponent implements OnChanges { onChanges(): void {...} } // ES5 var MyComponent = ng .Component({...}) .Class({ onChanges: function() { } });
1 parent 67b9414 commit 8302aff

File tree

42 files changed

+308
-839
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+308
-839
lines changed

modules/angular2/metadata.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export {
1414
ComponentMetadata,
1515
DirectiveMetadata,
1616
PipeMetadata,
17-
LifecycleEvent,
1817
ViewMetadata,
1918
ViewEncapsulation,
2019
QueryMetadata,
@@ -50,6 +49,8 @@ export {
5049
} from './src/core/metadata';
5150

5251
export {
52+
// todo(vbe): LifecycleHook should not be exposed (fails test.typings)
53+
LifecycleHook,
5354
AfterContentInit,
5455
AfterContentChecked,
5556
AfterViewInit,
Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,9 @@
11
library angular2.src.core.compiler.directive_lifecycle_reflector;
22

3-
import 'package:angular2/src/core/metadata.dart';
4-
import 'package:angular2/src/core/compiler/interfaces.dart';
53
import 'package:angular2/src/core/reflection/reflection.dart';
64

7-
bool hasLifecycleHook(LifecycleEvent e, type, DirectiveMetadata annotation) {
8-
if (annotation.lifecycle != null) {
9-
return annotation.lifecycle.contains(e);
10-
} else {
11-
if (type is! Type) return false;
5+
bool hasLifecycleHook(/*LifecycleHook*/ interface, type) {
6+
if (type is! Type) return false;
127

13-
final List interfaces = reflector.interfaces(type);
14-
var interface;
15-
16-
if (e == LifecycleEvent.OnChanges) {
17-
interface = OnChanges;
18-
} else if (e == LifecycleEvent.OnDestroy) {
19-
interface = OnDestroy;
20-
} else if (e == LifecycleEvent.AfterContentInit) {
21-
interface = AfterContentInit;
22-
} else if (e == LifecycleEvent.AfterContentChecked) {
23-
interface = AfterContentChecked;
24-
} else if (e == LifecycleEvent.AfterViewInit) {
25-
interface = AfterViewInit;
26-
} else if (e == LifecycleEvent.AfterViewChecked) {
27-
interface = AfterViewChecked;
28-
} else if (e == LifecycleEvent.DoCheck) {
29-
interface = DoCheck;
30-
} else if (e == LifecycleEvent.OnInit) {
31-
interface = OnInit;
32-
}
33-
34-
return interfaces.contains(interface);
35-
}
8+
return reflector.interfaces(type).contains(interface);
369
}
Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
1-
import {Type, isPresent} from 'angular2/src/core/facade/lang';
2-
import {LifecycleEvent, DirectiveMetadata} from 'angular2/metadata';
1+
import {Type} from 'angular2/src/core/facade/lang';
2+
import * as Interfaces from './interfaces';
33

4-
export function hasLifecycleHook(e: LifecycleEvent, type, annotation: DirectiveMetadata): boolean {
5-
if (isPresent(annotation.lifecycle)) {
6-
return annotation.lifecycle.indexOf(e) !== -1;
7-
} else {
8-
if (!(type instanceof Type)) return false;
9-
var proto = (<any>type).prototype;
10-
switch (e) {
11-
case LifecycleEvent.AfterContentInit:
12-
return !!proto.afterContentInit;
13-
case LifecycleEvent.AfterContentChecked:
14-
return !!proto.afterContentChecked;
15-
case LifecycleEvent.AfterViewInit:
16-
return !!proto.afterViewInit;
17-
case LifecycleEvent.AfterViewChecked:
18-
return !!proto.afterViewChecked;
19-
case LifecycleEvent.OnChanges:
20-
return !!proto.onChanges;
21-
case LifecycleEvent.DoCheck:
22-
return !!proto.doCheck;
23-
case LifecycleEvent.OnDestroy:
24-
return !!proto.onDestroy;
25-
case LifecycleEvent.OnInit:
26-
return !!proto.onInit;
27-
default:
28-
return false;
29-
}
4+
export function hasLifecycleHook(lcInterface: Interfaces.LifecycleHook, type): boolean {
5+
if (!(type instanceof Type)) return false;
6+
7+
var proto = (<any>type).prototype;
8+
9+
switch (lcInterface) {
10+
case Interfaces.AfterContentInit:
11+
return !!proto.afterContentInit;
12+
case Interfaces.AfterContentChecked:
13+
return !!proto.afterContentChecked;
14+
case Interfaces.AfterViewInit:
15+
return !!proto.afterViewInit;
16+
case Interfaces.AfterViewChecked:
17+
return !!proto.afterViewChecked;
18+
case Interfaces.OnChanges:
19+
return !!proto.onChanges;
20+
case Interfaces.DoCheck:
21+
return !!proto.doCheck;
22+
case Interfaces.OnDestroy:
23+
return !!proto.onDestroy;
24+
case Interfaces.OnInit:
25+
return !!proto.onInit;
26+
default:
27+
return false;
3028
}
3129
}

modules/angular2/src/core/compiler/element_injector.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import * as avmModule from './view_manager';
3939
import {ViewContainerRef} from './view_container_ref';
4040
import {ElementRef} from './element_ref';
4141
import {TemplateRef} from './template_ref';
42-
import {DirectiveMetadata, ComponentMetadata, LifecycleEvent} from '../metadata/directives';
42+
import {DirectiveMetadata, ComponentMetadata} from '../metadata/directives';
4343
import {hasLifecycleHook} from './directive_lifecycle_reflector';
4444
import {
4545
ChangeDetector,
@@ -51,6 +51,8 @@ import {RenderDirectiveMetadata} from 'angular2/src/core/render/api';
5151
import {EventConfig} from 'angular2/src/core/render/event_config';
5252
import {PipeBinding} from '../pipes/pipe_binding';
5353

54+
import * as LifecycleHooks from './interfaces';
55+
5456
var _staticKeys;
5557

5658
export class StaticKeys {
@@ -160,14 +162,14 @@ export class DirectiveBinding extends ResolvedBinding {
160162
properties: meta.properties,
161163
readAttributes: DirectiveBinding._readAttributes(<any>deps),
162164

163-
callOnDestroy: hasLifecycleHook(LifecycleEvent.OnDestroy, token, meta),
164-
callOnChanges: hasLifecycleHook(LifecycleEvent.OnChanges, token, meta),
165-
callDoCheck: hasLifecycleHook(LifecycleEvent.DoCheck, token, meta),
166-
callOnInit: hasLifecycleHook(LifecycleEvent.OnInit, token, meta),
167-
callAfterContentInit: hasLifecycleHook(LifecycleEvent.AfterContentInit, token, meta),
168-
callAfterContentChecked: hasLifecycleHook(LifecycleEvent.AfterContentChecked, token, meta),
169-
callAfterViewInit: hasLifecycleHook(LifecycleEvent.AfterViewInit, token, meta),
170-
callAfterViewChecked: hasLifecycleHook(LifecycleEvent.AfterViewChecked, token, meta),
165+
callOnDestroy: hasLifecycleHook(LifecycleHooks.OnDestroy, token),
166+
callOnChanges: hasLifecycleHook(LifecycleHooks.OnChanges, token),
167+
callDoCheck: hasLifecycleHook(LifecycleHooks.DoCheck, token),
168+
callOnInit: hasLifecycleHook(LifecycleHooks.OnInit, token),
169+
callAfterContentInit: hasLifecycleHook(LifecycleHooks.AfterContentInit, token),
170+
callAfterContentChecked: hasLifecycleHook(LifecycleHooks.AfterContentChecked, token),
171+
callAfterViewInit: hasLifecycleHook(LifecycleHooks.AfterViewInit, token),
172+
callAfterViewChecked: hasLifecycleHook(LifecycleHooks.AfterViewChecked, token),
171173

172174
changeDetection: meta instanceof ComponentMetadata ? meta.changeDetection : null,
173175

Lines changed: 156 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,181 @@
11
import {StringMap} from 'angular2/src/core/facade/collection';
2-
import {global} from 'angular2/src/core/facade/lang';
32

4-
// This is here only so that after TS transpilation the file is not empty.
5-
// TODO(rado): find a better way to fix this, or remove if likely culprit
6-
// https://github.com/systemjs/systemjs/issues/487 gets closed.
7-
var __ignore_me = global;
83
/**
9-
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnChanges `LifeCycleEvent.OnChanges`}
10-
* called after all of component's bound properties are updated.
4+
* Lifecycle hooks are guaranteed to be called in the following order:
5+
* - `OnChanges` (if any bindings have changed),
6+
* - `OnInit` (after the first check only),
7+
* - `DoCheck`,
8+
* - `AfterContentInit`,
9+
* - `AfterContentChecked`,
10+
* - `OnDestroy` (at the very end before destruction)
11+
*
12+
* // todo(vicb): describe Dart & TS vs JS
1113
*/
12-
export interface OnChanges { onChanges(changes: StringMap<string, any>): void; }
14+
export interface LifecycleHook {}
1315

1416
/**
15-
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnInit `LifeCycleEvent.OnInit`}
16-
* called when a directive is being checked the first time.
17+
* Notify a directive when any of its bindings have changed.
18+
*
19+
* `onChanges` is called right after the directive's bindings have been checked,
20+
* and before any of its children's bindings have been checked.
21+
*
22+
* It is invoked only if at least one of the directive's bindings has changed.
23+
*
24+
* ## Example:
25+
*
26+
* ```
27+
* @Component(...)
28+
* class MyComponent implements OnChanges {
29+
* propA;
30+
* propB;
31+
*
32+
* onChanges(changes: {[idx: string, PropertyUpdate]}): void {
33+
* // This will get called after any of the properties have been updated.
34+
* if (changes['propA']) {
35+
* // if propA was updated
36+
* }
37+
* if (changes['propA']) {
38+
* // if propB was updated
39+
* }
40+
* }
41+
* }
42+
* ```
1743
*/
18-
export interface OnInit { onInit(): void; }
44+
export class OnChanges implements LifecycleHook {
45+
onChanges(changes: StringMap<string, any>): void {}
46+
}
1947

2048
/**
21-
* Defines lifecycle method {@link metadata/LifeCycleEvent#DoCheck `LifeCycleEvent.DoCheck`}
22-
* called when a directive is being checked.
49+
* Notify a directive when it has been checked the first time.
50+
*
51+
* `onInit` is called right after the directive's bindings have been checked for the first time,
52+
* and before any of its children's bindings have been checked.
53+
*
54+
* It is invoked only once.
55+
*
56+
* ## Example
57+
*
58+
* ```
59+
* @Component(...)
60+
* class MyComponent @implements OnInit {
61+
* onInit(): void {
62+
* }
63+
* }
64+
* ```
2365
*/
24-
export interface DoCheck { doCheck(): boolean; }
66+
export class OnInit implements LifecycleHook {
67+
onInit(): void {}
68+
}
2569

2670
/**
27-
* Defines lifecycle method {@link metadata/LifeCycleEvent#OnDestroy `LifeCycleEvent.OnDestroy`}
28-
* called when a directive is being destroyed.
71+
* Overrides the default change detection.
72+
*
73+
* `doCheck()` gets called to check the changes in the directives instead of the default
74+
* change detection mechanism.
75+
*
76+
* It is invoked every time the change detection is triggered.
77+
*
78+
* ## Example
79+
*
80+
* ```
81+
* @Component(...)
82+
* class MyComponent implements DoCheck {
83+
* doCheck(): void {
84+
* // Custom logic to detect changes
85+
* }
86+
* }
87+
* ```
2988
*/
30-
export interface OnDestroy { onDestroy(): void; }
89+
export class DoCheck implements LifecycleHook {
90+
doCheck(): void {}
91+
}
3192

3293
/**
33-
* Defines lifecycle method
34-
* {@link metadata/LifeCycleEvent#AfterContentInit `LifeCycleEvent.afterContentInit`}
35-
* called when the bindings of all its content children have been checked the first time.
94+
* Notify a directive whenever a {@link ViewMetadata} that contains it is destroyed.
95+
*
96+
* ## Example
97+
*
98+
* ```
99+
* @Component(...)
100+
* class MyComponent implements OnDestroy {
101+
* onDestroy(): void {
102+
* // invoked to notify directive of the containing view destruction.
103+
* }
104+
* }
105+
* ```
36106
*/
37-
export interface AfterContentInit { afterContentInit(): void; }
107+
export class OnDestroy implements LifecycleHook {
108+
onDestroy(): void {}
109+
}
38110

39111
/**
40-
* Defines lifecycle method
41-
* {@link metadata/LifeCycleEvent#AfterContentChecked `LifeCycleEvent.afterContentChecked`}
42-
* called when the bindings of all its content children have been checked.
112+
* Notify a directive when the bindings of all its content children have been checked the first
113+
* time (whether they have changed or not).
114+
*
115+
* ## Example
116+
*
117+
* ```
118+
* @Component(...)
119+
* class MyComponent implements AfterContentInit {
120+
* afterContentInit(): void {
121+
* }
122+
* }
123+
* ```
43124
*/
44-
export interface AfterContentChecked { afterContentChecked(): void; }
125+
export class AfterContentInit implements LifecycleHook {
126+
afterContentInit(): void {}
127+
}
45128

46129
/**
47-
* Defines lifecycle method
48-
* {@link metadata/LifeCycleEvent#AfterViewInit `LifeCycleEvent.afterViewInit`}
49-
* called when the bindings of all its view children have been checked the first time.
130+
* Notify a directive when the bindings of all its content children have been checked (whether
131+
* they have changed or not).
132+
*
133+
* ## Example
134+
*
135+
* ```
136+
* @Component(...)
137+
* class MyComponent implements AfterContentChecked {
138+
* afterContentChecked(): void {
139+
* }
140+
* }
141+
* ```
50142
*/
51-
export interface AfterViewInit { afterViewInit(): void; }
143+
export class AfterContentChecked implements LifecycleHook {
144+
afterContentChecked(): void {}
145+
}
52146

53147
/**
54-
* Defines lifecycle method
55-
* {@link metadata/LifeCycleEvent#AfterViewChecked `LifeCycleEvent.afterViewChecked`}
56-
* called when the bindings of all its view children have been checked.
148+
* Notify a directive when the bindings of all its view children have been checked the first time
149+
* (whether they have changed or not).
150+
*
151+
* ## Example
152+
*
153+
* ```
154+
* @Component(...)
155+
* class MyComponent implements AfterViewInit {
156+
* afterViewInit(): void {
157+
* }
158+
* }
159+
* ```
57160
*/
58-
export interface AfterViewChecked { afterViewChecked(): void; }
161+
export class AfterViewInit implements LifecycleHook {
162+
afterViewInit(): void {}
163+
}
164+
165+
/**
166+
* Notify a directive when the bindings of all its view children have been checked (whether they
167+
* have changed or not).
168+
*
169+
* ## Example
170+
*
171+
* ```
172+
* @Component(...)
173+
* class MyComponent implements AfterViewChecked {
174+
* afterViewChecked(): void {
175+
* }
176+
* }
177+
* ```
178+
*/
179+
export class AfterViewChecked implements LifecycleHook {
180+
afterViewChecked(): void {}
181+
}

modules/angular2/src/core/directives/ng_class.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {isPresent, isString, StringWrapper, isBlank} from 'angular2/src/core/facade/lang';
2-
import {Directive, LifecycleEvent} from 'angular2/metadata';
2+
import {Directive, DoCheck, OnDestroy} from 'angular2/metadata';
33
import {ElementRef} from 'angular2/core';
44
import {Renderer} from 'angular2/src/core/render/api';
55
import {
@@ -34,12 +34,8 @@ import {
3434
* </div>
3535
* ```
3636
*/
37-
@Directive({
38-
selector: '[ng-class]',
39-
lifecycle: [LifecycleEvent.DoCheck, LifecycleEvent.OnDestroy],
40-
properties: ['rawClass: ng-class', 'initialClasses: class']
41-
})
42-
export class NgClass {
37+
@Directive({selector: '[ng-class]', properties: ['rawClass: ng-class', 'initialClasses: class']})
38+
export class NgClass implements DoCheck, OnDestroy {
4339
private _differ: any;
4440
private _mode: string;
4541
private _initialClasses = [];

0 commit comments

Comments
 (0)