AngularJS - Scope Experiment

This is an illustration as to how $apply() works.

by dmitri14

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<!-- This controller is listening for handleBroadcast on $rootScope -->
<div ng-controller="ControllerZero">
    <input ng-model="message" >
    <!-- This broadcasts to every controller 
         that is listening on $rootScope -->
    <button ng-click="handleClick(message);">BROADCAST</button>
</div>

<!-- This controller is listening for handleBroadcast on $rootScope -->
<div ng-controller="ControllerOne">
    <input ng-model="message" >
</div>

<!-- This controller is listening for handleBroadcast on $rootScope -->
<div ng-controller="ControllerTwo">
    <input ng-model="message" >
</div>

<!-- This directive is also listening for handleBroadcast on $rootScope -->
<my-component ng-model="message"></my-component>

JavaScript

var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
    var sharedService = {};

    sharedService.message = '';

    sharedService.prepForBroadcast = function(msg) {
        this.message = msg;
        this.broadcastItem();
    };

    sharedService.broadcastItem = function() {
        $rootScope.$broadcast('handleBroadcast');
    };

    return sharedService;
});

myModule.directive('myComponent', function(mySharedService) {
    return {
        restrict: 'E',
        controller: function($scope, $attrs, mySharedService) {
            $scope.$on('handleBroadcast', function() {
                $scope.message = 'Directive: ' + mySharedService.message;
            });
            $scope.handleClick = function(msg) {
                mySharedService.prepForBroadcast(msg);
            };            
        },
        link: function($scope, $element, $attrs) {
            $('.testButtonWithApply').on('click', function(){
                $scope.$apply(function() {
                    $scope.handleClick('Scope apply');
                });
            });
            
            $('.testButtonWithoutApply').on('click', function(){
                $scope.handleClick('This will not work');
            });            
        },
        replace: true,
        template: '<div><input ng-model="message"> <button ng-click="handleClick(\'Via controller\')">VIA CONTROLLER</button> <button class="testButtonWithApply">WITH APPLY</button> <button class="testButtonWithoutApply")">WITHOUT APPLY</button></div>'
    };
});

function ControllerZero($scope, sharedService) {
    $scope.handleClick = function(msg) {
        sharedService.prepForBroadcast(msg);
    };

    $scope.$on('handleBroadcast', function() {
        $scope.message = sharedService.message;
    });
}

function ControllerOne($scope, sharedService) {
    $scope.$on('handleBroadcast', function() {
        $scope.message = 'ONE: ' + sharedService.message;
   ...