Adding zone.js to Angular 1.4

27 ביוני 2015

tags: , ,
one comment

(I find below bits quite useful so I add them to github. You can get them by using bower install angular1-zones)

One of the cool features of Angular 2 is that there is no need to call $scope.$apply. This is true even if you are using 3rd party asynchronous library which Angular is unaware of.

The magic resides inside Angular 2 library named zone.js

The library overrides all standard browser APIs that are considered asynchronous. zone.js injects its own implementation and uses it to monitor the start and completion of any asynchronous activity.

Consider the following Angular 1.4 source code

function HomeCtrl($scope) {
    $scope.change = function () {
        setTimeout(function () {
            $scope.message = "XXX";
        }, 1000);
    }
}

This is a plain controller that uses setTimeout and changes some data model

Under Angular 1.4 the change is not detected by Angular since it is unaware of the asynchrounous activity excuted by setTimeout. As a result the developer must use $scope.$apply

function HomeCtrl($scope) {
    $scope.change = function () {
        setTimeout(function () {
            $scope.$apply(function () {
                $scope.message = "XXX";
            });
        }, 1000);
    }
}

We can intergate zone.js into Angular 1.4 too. See below

angular.module("ngZone", []).run(["$rootScope"function ($rootScope) {
    var scopePrototype = $rootScope.constructor.prototype;
 
    var originalApply = scopePrototype.$apply;
 
    var zoneOptions = {
        afterTask: function () {
            try {
                $rootScope.$digest();
            } catch (e) {
                $exceptionHandler(e);
                throw e;
            }
        }
    };
 
    scopePrototype.$apply = function () {
        var scope = this;
        var applyArgs = arguments;
 
        zone.fork(zoneOptions).run(function () {
            originalApply.apply(scope, applyArgs);
        });
    }
}]);

Above code define a new module named ngZone. The module overrides Angular's $scope.$apply. The new implementation wraps Angular's code with a zone fork.This way we can be notified by zone.js when an asynchronous activity is completed.

To test our code we need to add a module dependency

angular.module("MyApp", ["ngZone"]);

Now, lets execute the original controller code (without $scope.$apply). This time the change is detected by Angular.

Cool, don't you think ?

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. תומר קיסר27 ביוני 2015 ב 23:01

    מאוד יפה

    Reply