1

I've seen a couple posts, but for some reason I can't get my example to work. I even have old projects where this works fine, but the last two that I've attempted it has fallen flat.

The problem is I'm trying to pass a parameter back from my directive '&' inner function. I have two attacks, neither seem to work:

Attack1: Simply use the same callback name, nothing in link

angular.module('directiveBit', [])
  .controller('tst', function($scope) {
    $scope.thing = {
      crazy: 'filler'
    };

    $scope.whenClicked = function(thing) {
      console.log('the thing', thing);
      $scope.thing = thing;
    }
  })
  .directive('wok', function() {
    return {
      restrict: 'E',
      template: '<button ng-click="clicked({s:1})">Click Me</button>',
      scope: {
        clicked: '&'
      },
      link: function(scope, element, attr) {

      }
    }
  });

This seems to fail, the parameter sent into whenClicked is always undefined. http://embed.plnkr.co/IpbIwzmxUrKgJqZ0DExI/script.js

Attack 2: Use the link function and call a different function within the directive:

angular.module('directiveBit', [])
  .controller('tst', function($scope) {
    $scope.thing = {
      crazy: 'filler'
    };

    $scope.whenClicked = function(thing) {
      console.log('the thing', thing);
      $scope.thing = thing;
    }
  })
  .directive('wok', function() {
    return {
      restrict: 'E',
      template: '<button ng-click="doIt({s:1})">Click Me</button>',
      scope: {
        clicked: '&'
      },
      link: function(scope, element, attr) {
        scope.doIt = function(theThing) {
          scope.clicked({a: theThing});
        }
      }
    }
  });

Again this seems to fail. It calls the whenClicked function but still has nothing in the parameter. http://embed.plnkr.co/VKXF5Yz2lYcKpKdS8pvE/script.js

Does anyone know what simple thing I'm missing here?

0

2 Answers 2

1

Tricky part about the function binding is that you need to specify the argument name in the bound function exactly same as the key used in the object passed in. In your example the object passed in is {s:someStuff} so when you bind the function it should be :

 <wok clicked="whenClicked(s)"></wok>

But instead of s you are using a different argument name say thi which is not a property of the passed in object from the directive so you get no value, In order for angular parser to parse the value of property s and pass it as argument to the referenced function.

angular.module('directiveBit', [])
  .controller('tst', function($scope) {
    $scope.thing = {
      crazy: 'filler'
    };

    $scope.whenClicked = function(thing) {
      console.log('the thing', thing);
      $scope.thing = thing;
    }
  })
  .directive('wok', function() {
    return {
      restrict: 'E',
      template: '<button ng-click="clicked({s:1})">Click Me</button>',
      scope: {
        clicked: '&'
      },
      link: function(scope, element, attr) {

      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<div ng-app="directiveBit" ng-controller="tst">
  <wok clicked="whenClicked(s)"></wok>
</div>

Documentation

Often it's desirable to pass data from the isolate scope via an expression to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, the hideDialog function takes a message to display when the dialog is hidden. This is specified in the directive by calling close({message: 'closing for now'}). Then the local variable message will be available within the on-close expression.

But if you use 2-way binding with function reference,

clicked: '='

you could do

$scope.clicked(anyStuff);

or

template: '<button ng-click="clicked(1)">Click Me</button>',

and used as :

<wok clicked="whenClicked"></wok>

angular.module('directiveBit', [])
  .controller('tst', function($scope) {
    $scope.thing = {
      crazy: 'filler'
    };

    $scope.whenClicked = function(thing) {
      console.log('the thing', thing);
      $scope.thing = thing;
    }
  })
  .directive('wok', function() {
    return {
      restrict: 'E',
      template: '<button ng-click="clicked(1)">Click Me</button>',
      scope: {
        clicked: '='
      },
      link: function(scope, element, attr) {

      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
<div ng-app="directiveBit" ng-controller="tst">
  <wok clicked="whenClicked"></wok>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! I would have to say the documentation doesn't seem to make that entirely clear and normally one would think the actual name of the parameter shouldn't make a difference. I would personally think the object itself would be sent through, not a serialized argument = key type thing.
@Chris Yup you are right. Documentation has not been explicit/clear on the function binding argument passing stuff. I think everybody gets into this issue when used for the first time. :)
0

Chris

You forgot to name your parameters, you named "clicked({thi:1})" what should be "clicked({thi:1})", which is your param name

Check out this plunker

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.