d_z90
d_z90

Reputation: 1263

Pass scope value from Directive to Controller - AngularJS

I have a small script with a countdown, created through a directive, which starts if a $scope value inside the controller is true. This is the html code:

<countdown from="3" start-if="{{startCountdown}}"></countdown>

Followed by the code of the directive:

app.directive('countdown', function ($interval) {
  return {
    restrict: 'E',
    template: '{{count}}',
    controller: function($scope, $element, $attrs) {
      $scope.count = $attrs.from;

      function countdown(){
        var intervalID = $interval(function() {
          if ($scope.count > 0) {
            $scope.count--;
          } else {
            $interval.cancel(intervalID);
          }
        }, 1000);
      }

      $attrs.$observe('startIf', function(value) {
        if (value) {
          countdown();
        }
      });
    }
  }
});

The countdown is working properly but inside the controller, if $scope.count === 0, there should be an alert() but it is not working.

This is a Plnkr with the complete code. Do you know how to pass the value of $scope.count to the controller and solve this issue? Thanks in advance for your replies!

Upvotes: 0

Views: 1715

Answers (2)

Umakanta Behera
Umakanta Behera

Reputation: 265

You can use $broadcast to achieve this with same code.

controller: function($scope, $element, $attrs, $rootScope) {
  $scope.count = $attrs.from;

  function countdown(){
    var intervalID = $interval(function() {
      $rootScope.$broadcast('counterVal',{
          countVal:$scope.count
        });
      if ($scope.count > 0) {
        $scope.count--;

      } else {
        $interval.cancel(intervalID);
      }
    }, 1000);
  }

  $attrs.$observe('startIf', function(value) {
    if (value) {
      countdown();
    }
  });
}

Please find the working plunker here.

Upvotes: 1

Maciej Sikora
Maciej Sikora

Reputation: 20132

I. Child scope directive.

You did not created isolated scope, so easiest solution is to remove from attribute and init count scope variable in controller. So:

//controller code
//init variable
$scope.count=3;

//directive code
//manipulate variable
$scope.count--;

Example with directive without isolated scope ( child scope ):

var app=angular.module("app",[]);
app.controller("controller",function($scope,$timeout){

   $scope.count=2;
   $scope.start=false;//start countdown flag


   $scope.$watch("count",function(val){
   
     console.log("Count is changed to:"+val);
     
   });
  
});

app.directive("myDirective",function($timeout){

   return{
     restrict:"E",
     template:"{{count}}",
     link:function(scope){
     
       scope.count++;//example change
  
       $timeout(function() { scope.count++; },2000);//example change

       scope.$watch("start",function(){
         
            //here we watch changes in start scope variable
            //here start countdown

       });
       
     }
   }
   
  
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
  <my-directive></my-directive>
</div>  

II. Isolated scope directive

You can also do the same thing with isolated scope, it need to pass variable by = ( two way binding ). Example:

    var app=angular.module("app",[]);
    app.controller("controller",function($scope){

       $scope.count=2;
      
       $scope.$watch("count",function(val){
       
         console.log("Count is changed to:"+val);
         
       });
      
    });

    app.directive("myDirective",function($timeout){

       return{
         restrict:"E",
         scope:{
         count:"="//pass variable to isolated scope
         },
         template:"{{count}}",
         link:function(scope){
         
           scope.count++;//example change
      
           $timeout(function() { scope.count++; },2000);//example change
           
         }
       }
       
      
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app" ng-controller="controller">
      <my-directive count="count" ></my-directive>
    </div>  

Upvotes: 2

Related Questions