0

I'm reading a angularJS book, and found a not working sample code =/. I'm searching but didn't find an answer. Basically I'm testing the "controller" option of a directive, the code uses a template that have a expression that evaluate a value ("goals") of the directive controller scope. But the value is not being update, I don't know why.

Here is the code: (fiddle)

HTML

<div ng-app="myApp">
    <div goal game time="Cruze vs Holy" ></div>
</div>

JS

var app = angular.module('myApp', []);

app.directive('game', function () {
   return {
       scope: {
           times: '@'
       },
       controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
           $scope.goals = 0;
           this.increment = function() {
               $scope.goals++;
               console.log($scope.goals);
               alert("goals = " + $scope.goals);
           }
       }],
       template: "<p>Match: [{{times}}]</p><b>Match goals: </b> {{goals}}"
   };
});

app.directive('goal', function() {
    return {
        require: 'game',
        link: function (scope, el, attrs, gameController) {
            var b = angular.element("<p><button>Increase Match goals</button></p>");
            b.on('click', function() {
                gameController.increment();
            });
            el.append(b);
        }
    };
});
Rafael Teles
  • 2,708
  • 2
  • 16
  • 32

2 Answers2

0

You should call the $apply after change the scope variable.

var app = angular.module('myApp', []);

app.directive('game', function () {
   return {
       scope: {
           times: '@'
       },
       require: '^ngModel',
       controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
           $scope.goals = 0;
           this.increment = function() {
               $scope.goals++;
               console.log($scope.goals);
               $scope.$apply();
           }
       }],
       template: '<p>Match: [{{times}}]</p><b>Match goals: <span ng-bind="goals"></span></b> {{goals}}'
   };
});

app.directive('goal', function() {
    return {
        require: 'game',
        link: function (scope, el, attrs, gameController) {
            var b = angular.element("<p><button>Increase Match goals</button></p>");
            b.on('click', function() {
                gameController.increment();
            });
            el.append(b);
        }
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<div ng-app="myApp">
    <div goal game time="Cruze vs Holy" ></div>
</div>
Bruno João
  • 5,105
  • 2
  • 21
  • 26
0

Thanks @vinagreti and @mutil.

Just to explain for others that have the same problem, you need to use $apply (or $digest depending on the situation) when you are changing some scope variable from "outside" the angular environment, since the "onclick" event was generated by pure javascript and not a Angular event (ng-click for instance) you have to call $apply to make the changes in the scope to be applied to the view

Rafael Teles
  • 2,708
  • 2
  • 16
  • 32