diff --git a/lib/core/zone.dart b/lib/core/zone.dart index 3c443beaf..600b775aa 100644 --- a/lib/core/zone.dart +++ b/lib/core/zone.dart @@ -29,8 +29,13 @@ class LongStackTrace { * A better zone API which implements onTurnDone. */ class NgZone { - NgZone() { - _zone = async.Zone.current.fork(specification: new async.ZoneSpecification( + final async.Zone _outerZone; + async.Zone _zone; + + NgZone() + : _outerZone = async.Zone.current + { + _zone = _outerZone.fork(specification: new async.ZoneSpecification( run: _onRun, runUnary: _onRunUnary, scheduleMicrotask: _onScheduleMicrotask, @@ -38,7 +43,6 @@ class NgZone { )); } - async.Zone _zone; List _asyncQueue = []; bool _errorThrownFromOnRun = false; @@ -142,6 +146,22 @@ class NgZone { */ run(body()) => _zone.run(body); + /** + * Allows one to escape the auto-digest mechanism of Angular. + * + * myFunction(NgZone zone, Element element) { + * element.onClick.listen(() { + * // auto-digest will run after element click. + * }); + * zone.runOutsideAngular(() { + * element.onMouseMove.listen(() { + * // auto-digest will NOT run after mouse move + * }); + * }); + * } + */ + runOutsideAngular(body()) => _outerZone.run(body); + assertInTurn() { assert(_runningInTurn > 0 || _inFinishTurn); } diff --git a/test/core/zone_spec.dart b/test/core/zone_spec.dart index 1725d837b..a50b1c9a0 100644 --- a/test/core/zone_spec.dart +++ b/test/core/zone_spec.dart @@ -46,6 +46,23 @@ main() => describe('zone', () { }))); + it('should allow executing code outside the zone', inject(() { + var zone = new NgZone(); + var outerZone = Zone.current; + var ngZone; + var outsideZone; + zone.run(() { + ngZone = Zone.current; + zone.runOutsideAngular(() { + outsideZone = Zone.current; + }); + }); + + expect(outsideZone).toEqual(outerZone); + expect(ngZone.parent).toEqual((outerZone)); + })); + + it('should rethrow exceptions from the onTurnDone and call onError when the zone is sync', () { zone.onTurnDone = () { throw ["fromOnTurnDone"];