Angular JS Magazine

sâmbătă, 13 septembrie 2014

Communicating Between Scopes

In tip Reusing a Controller you saw that the same controller can be used in the same application in multiple views, because, for each view, the factory method will create a separate controller instance and a separate scope. Well, remember counter A and counter B from that example? Now, let's suppose that we want to obtain counter A value + counter B value each time one of the counters is increased. For this, we need to provide a comunication between these two scopes, which means that we have to know that:

- scopes are organized in a hierarchy, starting with the root scope (represented by $rootScope).
- each scope is a child of root scope
- communication between scopes is possible thanks to events sent by the root scope
- those events are (source of the below image: Pro AngularJS, by Adam Freeman):

- $broadcast and $emit events are capable to send an event up through the scope hierarchy until it reaches the root scope or down through the hierarchy to each of the child scopes

Now, we can summarize these bullets under the below lines:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="../angular/angular.min.js"></script>
    <script>
        angular.module("atpModule", [])
                .controller("atpCtrl", function ($scope, $rootScope) {
                    $scope.counter = 0;

                    $scope.increaseCounter = function (type) {
                        $scope.counter = $scope.counter + 1;
                        console.log("Type: " + type + " Value:" + $scope.counter);
                        $rootScope.$broadcast("counterAorBWasUpdated", {
                            type: type, counter: $scope.counter
                        });
                    }

                    $scope.$on("counterAorBWasUpdated", function (event, args) {
                        $scope[args.type] = args.counter;
                    });

                    $scope.sumCounter = function () {
                        $scope.A = $scope.A || 0;
                        $scope.B = $scope.B || 0;
                        return $scope.A + $scope.B;
                    }
                });
    </script>
</head>
<body ng-app="atpModule">
<div ng-controller="atpCtrl">
    Counter A value: {{counter}}
    <br/>
    Total A + B: {{sumCounter()}}
    <button class="btn btn-primary" ng-click="increaseCounter('A')">
        Increase Counter A
    </button>
</div>
<hr/>
<div ng-controller="atpCtrl">
    Counter B value: {{counter}}
    <br/>
    Total A + B: {{sumCounter()}}
    <button class="btn btn-primary" ng-click="increaseCounter('B')">
        Increase Counter B
    </button>
</div>

</body>
</html>

 The console output is: