fix(life_cycle): throw when recursively reentering LifeCycle.tick

This commit is contained in:
vsavkin 2015-06-10 17:21:30 -07:00
parent 15dab7c5b2
commit af35ab56a3
2 changed files with 52 additions and 4 deletions

View File

@ -2,7 +2,7 @@ import {Injectable} from 'angular2/di';
import {ChangeDetector} from 'angular2/change_detection';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
import {isPresent} from 'angular2/src/facade/lang';
import {isPresent, BaseException} from 'angular2/src/facade/lang';
/**
* Provides access to explicitly trigger change detection in an application.
@ -36,6 +36,7 @@ export class LifeCycle {
_errorHandler;
_changeDetector: ChangeDetector;
_enforceNoNewChanges: boolean;
_runningTick: boolean = false;
constructor(exceptionHandler: ExceptionHandler, changeDetector: ChangeDetector = null,
enforceNoNewChanges: boolean = false) {
@ -75,9 +76,18 @@ export class LifeCycle {
*
*/
tick() {
this._changeDetector.detectChanges();
if (this._enforceNoNewChanges) {
this._changeDetector.checkNoChanges();
if (this._runningTick) {
throw new BaseException("LifeCycle.tick is called recursively");
}
try {
this._runningTick = true;
this._changeDetector.detectChanges();
if (this._enforceNoNewChanges) {
this._changeDetector.checkNoChanges();
}
} finally {
this._runningTick = false;
}
}
}

View File

@ -0,0 +1,38 @@
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el,
AsyncTestCompleter,
fakeAsync,
tick,
SpyObject,
inject,
proxy
} from 'angular2/test_lib';
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
import {ChangeDetector} from 'angular2/change_detection';
import {IMPLEMENTS} from 'angular2/src/facade/lang';
@proxy
@IMPLEMENTS(ChangeDetector)
class SpyChangeDetector extends SpyObject {
constructor() { super(ChangeDetector); }
noSuchMethod(m) { return super.noSuchMethod(m) }
}
export function main() {
describe("LifeCycle", () => {
it("should throw when reentering tick", () => {
var cd = <any>new SpyChangeDetector();
var lc = new LifeCycle(null, cd, false);
cd.spy("detectChanges").andCallFake(() => lc.tick());
expect(() => lc.tick()).toThrowError("LifeCycle.tick is called recursively");
});
});
}