Search code examples
javascriptangularjsangular-directive

Access scope controller variable in Directive angular


I want to access Scope variable total in directive link property.

Even though total value is updating on mouseDown event was fired, but the $scope.total was not changing.

Here is the code

functionality: Total amount changes when mouse down on respective boxes

 var app = angular.module("billModule", []);
        app.controller("billController", function ($scope) {
            $scope.total = 0.0;
        });
        app.directive("menu", function ($document) {
            return {
                restrict: "EA",
                replace: true,
                link: function (scope, element, attr) {
                    element.on("mousedown", function () {
                        scope.total += Number(attr.cost);
                      //console.log("total is "+ scope.total);
                    });
                },
                template: function (element, attr) {

                    return "<div class='box' title='$" + attr.cost + "'>" + attr.item + "</div>";
                }
            }
        })
.box {
            width: 132px;height: 38px;background-color: red;cursor: pointer;border: groove;text-align: center;padding-top: 5px;font-size: 33px;color: white;
        }
            .box:hover {
                /*background-color: blue;*/
                border: inset;
            }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="billModule">
        <div ng-controller="billController">
            <menu item="Gold" cost="20"></menu>
            <menu item="fruits" cost="40"></menu>
            <menu item="phone" cost="90"></menu>
            <menu item="water" cost="50"></menu>
            <menu item="monitor" cost="70"></menu>
            <div>{{total | currency : '$':2}}</div>
        </div>

    </div>


Solution

  • Angular is not aware of the change, since it was made using an external event handler, and not an angular event handler (ngClick for example). To make angular aware of the change, wrap it with scope.$apply:

    scope.$apply(function() {
        scope.total += Number(attr.cost);
    });
    

    If you're using angular 1.3 or above, use scope.$applyAsync, as it's a bit more performant.