UltraSonja
UltraSonja

Reputation: 891

Passing variables from directive to controller

I'm having difficulty figuring out how to update a value from a click event. I have a custom directive that is basically a button switch. When the button is switched off, I want it to change the value of a certain variable to 0. When it is on, I want it to change the value of that variable to a number > 0.

I have created a plnkr to recreate the problem.

Also, I've read this post, which was somewhat helpful, but still has me scratching my head about how to approach my problem.

In the directive, I'm handling the click event and then trying to change the value of the variable, but it's never being changed in the view. I think I have to pass the value from the directive to the controller in order to propagate it to the view, but I'm not sure how to go about that.

angular
    .module('app')
    .directive('buttonToggle', buttonToggle);

function buttonToggle() {
  function link(scope, elm) {
    if(elm === "#btnToggle1") {
      angular.element(elm).on('click', function() {
        var confirmResponse = (window.confirm("Are you sure?") === true);

        if( confirmResponse ) {
           scope.on = !scope.on;
           scope.off = !scope.off;
           scope.$digest();

           if(scope.on) {
              $scope.switchBtnOutput = 8044; // var I'm trying to change
              return scope.off;
           } else if(scope.off) {
              $scope.switchBtnOutput = 0; // var I'm trying to change
              return scope.on;
           }
        }

        scope.$digest();
     });
    } else {
      angular.element(elm).on('click', function() {
        var confirmResponse = (window.confirm("Are you sure?") === true);

        if( confirmResponse ) {
           scope.on = !scope.on;
           scope.off = !scope.off;
           scope.$digest();
            if(scope.on) {
                return scope.off;
            } else if(scope.off) {
                return scope.on;
            }
        }

         scope.$digest();
      });
    }
  }

  var directive =  {
        restrict: 'AE',
        link: link,
        replace: true,
        templateUrl: 'buttonToggle.html',
        scope: {
            on: "=",
            off: "="
        }
    };

    return directive;
}

Upvotes: 0

Views: 179

Answers (1)

Petr Averyanov
Petr Averyanov

Reputation: 9476

Your directive introduces isolated scope, so directive scope.something is different from controller scope.something. Only variables you declare in scope : {...} got binded.

Btw, these directives need rework: 1. You can use ng-click in template - this will let you not to use crap digest call. 2. on == !off - so use one variable instead of 2. 3. $scope ={} << what this for.

So new template:

<div class="btn-group btn-toggle">
  <button class="btn btn-sm" ng-class="{'btn-success':on, 'btn-default':!on}" ng-click="toggle()" ng-disabled="on">ON</button>
  <button class="btn btn-sm" ng-class="{'btn-danger':!on, 'btn-default':on}" ng-click="toggle()" ng-disabled="!on">OFF</button>
</div>

Directive:

function buttonToggle()
{
  function link(scope, elm)
  {
    scope.toggle = function() {
        var confirmResponse = (window.confirm("Are you sure?") === true);

        if( confirmResponse ) {
          scope.on = !scope.on;
          scope.output = scope.output + 'Changed to ' + scope.on + '. ';
        }
    }
  }

    var directive = 
    {
        restrict: 'AE',
        link: link,
            replace: true,
        templateUrl: 'buttonToggle.html',
        scope: {
            on: "=",
            output: '='
        }
    };

    return directive;
}

working plunk http://plnkr.co/edit/qK8TMmjoxQ7rgKraryKp?p=preview

EDIT:

And here is the fixed plnk from the OP.

Upvotes: 1

Related Questions