Chapter 4: Manually bootstrapping an application

by msfrisbie

HTML

<script src="https://code.angularjs.org/1.3.2/angular.min.js"></script>
<div ng-app="myApp">
    <div ng-controller="Ctrl">
        <button ng-click="increment()">Increment</button>
        {{ val }}
    </div>
</div>

JavaScript

angular.module('myApp', [])
.controller('Ctrl', function ($scope) {
    $scope.safeApply = function (func) {
        var currentPhase = this.$root.$$phase;

        // determine if already in $apply/$digest phase
        if (currentPhase === '$apply' || 
            currentPhase === '$digest') {
            // already inside $apply/$digest phase

            // if safeApply() was passed a function, invoke it
            if (typeof(func) === 'function') {
                func();
            }
        } else {
            // not inside $apply/$digest phase, safe to invoke $apply
            this.$apply(func);
        }
    };

    $scope.val = 0;

    // method that may or may not be called from somewhere
    // that will not trigger a $digest
    $scope.increment = function () {
        $scope.val++;
        $scope.safeApply();
    };

    // application component that modifies the model without
    // triggering a $digest
    setInterval(function () {
        $scope.increment();
    }, 1000);
});