X Tutup
Skip to content

Commit af35ab5

Browse files
committed
fix(life_cycle): throw when recursively reentering LifeCycle.tick
1 parent 15dab7c commit af35ab5

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

modules/angular2/src/core/life_cycle/life_cycle.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Injectable} from 'angular2/di';
22
import {ChangeDetector} from 'angular2/change_detection';
33
import {NgZone} from 'angular2/src/core/zone/ng_zone';
44
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
5-
import {isPresent} from 'angular2/src/facade/lang';
5+
import {isPresent, BaseException} from 'angular2/src/facade/lang';
66

77
/**
88
* Provides access to explicitly trigger change detection in an application.
@@ -36,6 +36,7 @@ export class LifeCycle {
3636
_errorHandler;
3737
_changeDetector: ChangeDetector;
3838
_enforceNoNewChanges: boolean;
39+
_runningTick: boolean = false;
3940

4041
constructor(exceptionHandler: ExceptionHandler, changeDetector: ChangeDetector = null,
4142
enforceNoNewChanges: boolean = false) {
@@ -75,9 +76,18 @@ export class LifeCycle {
7576
*
7677
*/
7778
tick() {
78-
this._changeDetector.detectChanges();
79-
if (this._enforceNoNewChanges) {
80-
this._changeDetector.checkNoChanges();
79+
if (this._runningTick) {
80+
throw new BaseException("LifeCycle.tick is called recursively");
81+
}
82+
83+
try {
84+
this._runningTick = true;
85+
this._changeDetector.detectChanges();
86+
if (this._enforceNoNewChanges) {
87+
this._changeDetector.checkNoChanges();
88+
}
89+
} finally {
90+
this._runningTick = false;
8191
}
8292
}
8393
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
ddescribe,
3+
describe,
4+
it,
5+
iit,
6+
xit,
7+
expect,
8+
beforeEach,
9+
afterEach,
10+
el,
11+
AsyncTestCompleter,
12+
fakeAsync,
13+
tick,
14+
SpyObject,
15+
inject,
16+
proxy
17+
} from 'angular2/test_lib';
18+
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
19+
import {ChangeDetector} from 'angular2/change_detection';
20+
import {IMPLEMENTS} from 'angular2/src/facade/lang';
21+
22+
@proxy
23+
@IMPLEMENTS(ChangeDetector)
24+
class SpyChangeDetector extends SpyObject {
25+
constructor() { super(ChangeDetector); }
26+
noSuchMethod(m) { return super.noSuchMethod(m) }
27+
}
28+
29+
export function main() {
30+
describe("LifeCycle", () => {
31+
it("should throw when reentering tick", () => {
32+
var cd = <any>new SpyChangeDetector();
33+
var lc = new LifeCycle(null, cd, false);
34+
cd.spy("detectChanges").andCallFake(() => lc.tick());
35+
expect(() => lc.tick()).toThrowError("LifeCycle.tick is called recursively");
36+
});
37+
});
38+
}

0 commit comments

Comments
 (0)
X Tutup