14

I was looking for a way to find out how to call a function inside a directive from the controller. I got the snip but hence I am new to Angular, the below code flow is not very clear. Anyone mind to explain how the code is working. Thanks.

// Directive 
<map set-fn="setDirectiveFn(theDirFn)"></map>

scope: { setFn: '&' },
link: function(scope, element, attrs) {
    scope.updateMap = function() {
       alert('inside updateMap()');
    }
    scope.setFn({theDirFn: scope.updateMap});
}

// Controller
<button ng-click="directiveFn()">call directive function</button>
function MyCtrl($scope) {
    $scope.setDirectiveFn = function(directiveFn) {
        $scope.directiveFn = directiveFn;
    };
}

4 Answers 4

23

Starting with the controller, this block creates a setDirectiveFn() method on the $scope object in your controller that takes a single parameter (directiveFn) and then uses that parameter to create a directiveFn() method on the $scope object in your controller.

    $scope.setDirectiveFn = function(directiveFn) {
        $scope.directiveFn = directiveFn;
    };

Inside the directive it is creating an updateMap() method on the scope object in the directive and then calling the setFn() method which is mapped to the $scope.setDirectiveFn() method by this line: <map set-fn="setDirectiveFn(theDirFn)"></map> in your HTML and this line: scope: { setFn: '&' } in your directive. It is passing the scope.updateMap() method which effectively sets $scope.directiveFn() in your controller equal to scope.updateMap() in your directive.

link: function(scope, element, attrs) {
    scope.updateMap = function() {
       alert('inside updateMap()');
    }
    scope.setFn({theDirFn: scope.updateMap});
}

The button is then calling $scope.directiveFn() in your controller which has been mapped to scope.updateMap() in your directive.

<button ng-click="directiveFn()">call directive function</button>
Sign up to request clarification or add additional context in comments.

Comments

12

you can do it with angular pubsub

link: function(scope, element, attrs) {
    scope.updateMap = function() {
       alert('inside updateMap()');
    }
    scope.setFn({theDirFn: scope.updateMap});

    scope.$on('eventName', function(event, data){
       //call directive function here
    })
}

function MyCtrl($scope) {

      $scope.$broadcast('eventName', data)
}

Comments

3

Just call the directive function from your controller/template and initialise that function in your directive using two-way binding symbol

var app = angular.module('myApp', [])
 .controller('AppCtrl', function($scope){
 })
.directive('tabBar', function(){
return {
    restrict: 'E',
    scope: {
        tabClick: '='
    }, 
    templateUrl: 'templates/tabbar.tpl.html',
    link: function(scope) {
                    scope.tabClick = function(str) {
            alert(str);
        }
    }
   };
   });

Working sample

Note: Tested and working

Comments

1

I recommend reading this article : http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope

Basically, your directive has an Isolate Scope set by scope: {setFn: '&'}

What this does is that when you can send data to your directive via attributes, in this case, the set-fn attribute.

in your directive, scope.setFn now contains the function sent to it via attribute in your html (setDirectiveFn(theDirFn))

So calling scope.setFn({theDirFn: scope.updateMap});

Calls the function defined in

function MyCtrl($scope) {
    $scope.setDirectiveFn = function(directiveFn) {
         $scope.directiveFn = directiveFn;
    };
}

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.