Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Directive bind function with & not passing arguments to controller

I have a directive which interacts with Box file picker. My directive is used by 2 separate controllers, with the possibility of adding more in the future.

Box file picker lets you set a callback function once the user selects a file/folder, like this:

var boxSelect = new BoxSelect();
// Register a success callback handler
boxSelect.success(function(response) {
    console.log(response);
});

My controllers are using the directive and they have the success callback logic as scope variables, which I'm passing to the directive.

I created a plunkr where I'm mocking the Box select behavior

Controller

.controller('myController', function($scope) {
  $scope.onSuccessful = function(message) {
    alert('Success! Message: ' + message);
  };
})

Directive

angular.module('myApp', [])
  .controller('myController', function($scope) {
    $scope.onSuccessful = function(message) {
      //message is undefined here
      alert('Success! Message: ' + message);
    };
  })
  .directive('myDirective', function() {
    return {
      restrict: 'A',
      scope: {
        success: '&'
      },
      link: function(scope, element) {

        //third party allows to subscribe to success and failure functions
        function ThirdPartySelect() {

        }

        ThirdPartySelect.prototype.success = function(callback) {
          this.callback = callback;

        };

        ThirdPartySelect.prototype.fireSuccess = function() {
          this.callback({
            foo: 'bar'
          });
        };

        var myThirdPartyInstance = new ThirdPartySelect();
        myThirdPartyInstance.success(function(message) {
          //message is still defined here, but not in the controller
          scope.success(message);
        });

        element.on('click', function() {
          myThirdPartyInstance.fireSuccess();
        });

      }
    };
  });

View

<div ng-controller="myController">
  <button my-directive success="onSuccessful(arg)">Test</button>
</div>

The callback function gets called inside the controller but the arguments are undefined.

I was able to fix this by using '=' instead of '&', but I'd like to know why it wasn't working with '&' since it is supposed to be used for method binding

like image 565
yvesmancera Avatar asked Aug 13 '15 21:08

yvesmancera


People also ask

What is Angular bind function?

The angular. bind() Function in AngularJS is used to bind the current context to a function, but actually, execute it at a later time. It can also be used in Partial Applications. Partial Application is when you want to make a function but some of the arguments have been passed already.

What is @directive in Angular?

What is meant by directives in Angular? Directives are classes that add new behavior or modify the existing behavior to the elements in the template. Basically directives are used to manipulate the DOM, for example adding/removing the element from DOM or changing the appearance of the DOM elements.

What are the types of binding in Angular?

AngularJS provides two types of Data Binding: One-way data binding. Two-way data binding.


1 Answers

Yes, to bind a controller function to your directive, you have to use the & bindings (expression binding) which allows the directive to call an expression or a function defined by a DOM attribute.

But in your directive, when you call your binded method, the function parameter should be an object where the key are the same parameter that you declare in your controller, when you define your function.

So in your directive, you have to replace :

scope.success(message);

by :

scope.success({message:message.foo});

Then in your HTML, you have to replace :

 <button my-directive success="onSuccessful(arg)">Test</button>

by :

<button my-directive success="onSuccessful(message)">Test</button>

You can see the Working Plunker

like image 181
Paul Boutes Avatar answered Oct 07 '22 19:10

Paul Boutes