Skip to content

Commit 63f23ec

Browse files
Bertrand Laportemhevery
authored andcommitted
fix(life_cycle): remove cyclic dependency
fixes angular#477 Closes angular#530
1 parent 5010cf9 commit 63f23ec

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

modules/angular2/src/core/application.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function _injectorBindings(appComponentType) {
7878
[appViewToken]),
7979
bind(appComponentType).toFactory((rootView) => rootView.elementInjectors[0].getComponent(),
8080
[appViewToken]),
81-
bind(LifeCycle).toFactory((cd) => new LifeCycle(cd, assertionsEnabled()), [appChangeDetectorToken])
81+
bind(LifeCycle).toFactory(() => new LifeCycle(null, assertionsEnabled()),[])
8282
];
8383
}
8484

@@ -108,9 +108,11 @@ export function bootstrap(appComponentType: Type, bindings=null, givenBootstrapE
108108

109109
var appInjector = _createAppInjector(appComponentType, bindings);
110110

111-
PromiseWrapper.then(appInjector.asyncGet(LifeCycle),
112-
(lc) => {
113-
lc.registerWith(zone);
111+
PromiseWrapper.then(appInjector.asyncGet(appViewToken),
112+
(rootView) => {
113+
// retrieve life cycle: may have already been created if injected in root component
114+
var lc=appInjector.get(LifeCycle);
115+
lc.registerWith(zone, rootView.changeDetector);
114116
lc.tick(); //the first tick that will bootstrap the app
115117

116118
bootstrapProcess.complete(appInjector);

modules/angular2/src/core/life_cycle/life_cycle.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,29 @@ import {FIELD, print} from 'angular2/src/facade/lang';
22
import {ChangeDetector} from 'angular2/change_detection';
33
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
44
import {ListWrapper} from 'angular2/src/facade/collection';
5+
import {isPresent} from 'angular2/src/facade/lang';
56

67
export class LifeCycle {
78
_changeDetector:ChangeDetector;
89
_enforceNoNewChanges:boolean;
910

10-
constructor(changeDetector:ChangeDetector, enforceNoNewChanges:boolean = false) {
11-
this._changeDetector = changeDetector;
11+
constructor(changeDetector:ChangeDetector = null, enforceNoNewChanges:boolean = false) {
12+
this._changeDetector = changeDetector; // may be null when instantiated from application bootstrap
1213
this._enforceNoNewChanges = enforceNoNewChanges;
1314
}
1415

15-
registerWith(zone:VmTurnZone) {
16+
registerWith(zone:VmTurnZone, changeDetector:ChangeDetector = null) {
1617
// temporary error handler, we should inject one
1718
var errorHandler = (exception, stackTrace) => {
1819
var longStackTrace = ListWrapper.join(stackTrace, "\n\n-----async gap-----\n");
1920
print(`${exception}\n\n${longStackTrace}`);
2021
throw exception;
2122
};
2223

24+
if (isPresent(changeDetector)) {
25+
this._changeDetector=changeDetector;
26+
}
27+
2328
zone.initCallbacks({
2429
onErrorHandler: errorHandler,
2530
onTurnDone: () => this.tick()
@@ -32,4 +37,4 @@ export class LifeCycle {
3237
this._changeDetector.checkNoChanges();
3338
}
3439
}
35-
}
40+
}

modules/angular2/test/core/application_spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {ListWrapper} from 'angular2/src/facade/collection';
77
import {PromiseWrapper} from 'angular2/src/facade/async';
88
import {bind, Inject} from 'angular2/di';
99
import {TemplateConfig} from 'angular2/src/core/annotations/template_config';
10+
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
1011

1112
@Component({
1213
selector: 'hello-app',
@@ -51,6 +52,21 @@ class HelloRootCmp3 {
5152
}
5253
}
5354

55+
@Component({
56+
selector: 'hello-app',
57+
template: new TemplateConfig({
58+
inline: '',
59+
directives: []
60+
})
61+
})
62+
class HelloRootCmp4 {
63+
lc;
64+
65+
constructor(@Inject(LifeCycle) lc) {
66+
this.lc = lc;
67+
}
68+
}
69+
5470
export function main() {
5571
var fakeDoc, el, el2, testBindings;
5672

@@ -126,5 +142,14 @@ export function main() {
126142
done();
127143
});
128144
});
145+
146+
it("should avoid cyclic dependencies when root component requires Lifecycle through DI", (done) => {
147+
var injectorPromise = bootstrap(HelloRootCmp4, testBindings);
148+
149+
injectorPromise.then((injector) => {
150+
expect(injector.get(HelloRootCmp4).lc).toBe(injector.get(LifeCycle));
151+
done();
152+
});
153+
});
129154
});
130155
}

0 commit comments

Comments
 (0)