22

$scope.$apply will no longer be part of Angular 2. Then how do we let Angular know to update the DOM if any of the bound properties have been changed outside the regular angular execution context?

Taken from a blog post by Minko Gechev:

No more $scope.$apply

But how then AngularJS knows that anything outside it’s execution context has taken a place? Lets think where the changes might come from:

  • setTimeout
  • setInterval
  • prompt (yeah, there are people who still use it…)
  • XMLHttpRequest
  • WebSockets

For which the answer is:

enter image description here

I understand that patching the browser built-in javascript functions to notify of any changes to Angular is something that can be done in a relatively safe manner (without introducing subtle bugs) and would be very convenient for the developer. But what about third party APIs (such as jQuery.fadeIn) or if the browser exposes some new asynchronous API which isn't covered? What's the substitute for old $scope.$apply?

Jaanus Varus
  • 3,508
  • 3
  • 31
  • 49

2 Answers2

26
  1. import NgZone from core
  2. private zone: NgZone in your constructor
  3. this.zone.run(() => {}); where you would normally scope.$apply

or

  1. ChangeDetectorRef
  2. private chRef: ChangeDetectorRef
  3. chRef.detectChanges();
Post Impatica
  • 14,999
  • 9
  • 67
  • 78
15

So the library that does all this monkey patching is zone.js.

jQuery.fadeIn calls setInterval, setInterval is monkey patched, as long as you called jQuery.fadeIn within a zone.run.

zone.fork and zone.run kind of replace $scope.$apply, but it's different because it detects itself when asynchronous things have finished, whereas you have to call $scope.$apply manually when you know things have finished. See also this question+answer: Use zone.js to detect current execution context from anywhere?

if the browser exposes some new asynchronous API which isn't covered?

I guess they will patch that too.

If everything else fails, you can still call zone.afterTask() manually.
I guess that's what you were looking for :)

Community
  • 1
  • 1
Blaise
  • 13,139
  • 9
  • 69
  • 97
  • Thank you! Exactly what I was looking for. – Jaanus Varus Jun 09 '15 at 15:33
  • I'm seeing some internal google stuff like https://github.com/sararob/angular2base/blob/master/src/firebasepipe.ts using a ChangeDetectorRef instead - anybody know if that is the new hotness and the zone.afterTask() method is deprecated? Or what the relationship is there? – OverclockedTim Dec 14 '15 at 02:10
  • zone.afterTask() doesn't do anything for me at all. Is there something I need to do to hook that up to check for changes to ng2 views? – Ben Dilts Dec 16 '15 at 22:54
  • For anyone looking for how to include Zone in your Angular 2 project, see this: http://stackoverflow.com/questions/34381680/angular-2-change-detection and this http://www.angular-meteor.com/tutorials/socially/angular2/3-way-data-binding – Vern Jensen Dec 30 '15 at 21:11
  • Further to the above, an implementation of zone implementation in ES5 can be found here http://stackoverflow.com/questions/35287164/angular-2-0-beta-es5-ui-not-updating-via-custom-event – Stephen D. Feb 15 '16 at 15:50