Rafa
Rafa

Reputation: 2027

Calling user defined function from AngularJS directive

I am very new to AngularJS and I need to call a user defined function from a directive. In other words, in the example bellow I want to call the user defined function "whenSuccessFunction" when the user presses the button:

index.xml

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script type="text/javascript">
    var whenSuccessFunction = function(data) {
        alert(data);
    };
</script>
</head>
<body>
    <script src="vendor/angularjs/angular.js"></script>
    <script src="js/myapp.js"></script>
    <my-directive x-user-defined-function="whenSuccessFunction()"></my-directive>
</body>
</html>

myapp.js

var myApp = angular.module('myApp', []);

myApp.directive('myDirective', function() { 
    return {
        restrict: 'E',
        scope:true,
        template: '<button ng-click="doStuff()">Click here!</button>',
        controller: function($scope, $element) {
            $scope.doStuff = function() {
                console.log('Lots of different things happen here, including some asynchronous task');
                // Now, I need to call the user defined function
                var data = 1234;
                userDefinedFunction(data);
            };
        },      
        link: function(scope, elem, attrs, controllerInstance) {
            console.log(attrs.userDefinedFunction); // stings "whenSuccessFunction()"
        },
        scope: {
            // I think the answer for my issue is around the scope... but I do not know what to do next...
            userDefinedFunction: '=userDefinedFunction'
        }
    };
});

When I press the button it throws the following error:

Error: userDefinedFunction is not defined .controller/$scope.doStuff@..............

Any help would be highly appreciated.

Thanks

Upvotes: 2

Views: 1334

Answers (2)

dfsq
dfsq

Reputation: 193261

You have to define your callback function in the directive parent scope. Otherwise Angular will not find it and wont be able to invoke it. So for example:

<body ng-controller="MainCtrl">
    <my-directive x-user-defined-function="whenSuccessFunction(data)"></my-directive>
</body>

Then in controller:

myApp.controller('MainCtrl', function($scope) {
    $scope.whenSuccessFunction = function(data) {
        alert(data);
    };
});

And finally the directive also have a mistake:

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        template: '<button ng-click="doStuff()">Click here!</button>',
        controller: function($scope, $element) {
            $scope.doStuff = function() {
                console.log('Lots of different things happen here, including some asynchronous task');

                // this is how you pass data to the function
                $scope.userDefinedFunction({data: 1234});
            };
        },
        link: function(scope, elem, attrs, controllerInstance) {

        },

        // Use &userDefinedFunction to execute an expression
        scope: {
            userDefinedFunction: '&userDefinedFunction'
        }
    };
});

Demo: http://plnkr.co/edit/ks40nFnhSV15QiI8vx9o?p=preview

Upvotes: 1

Mik378
Mik378

Reputation: 22171

Remove the scope:true (used for scope inheritance, which is not your expectation) and replace it by:

scope: {
    userDefinedFunction: '&xUserDefinedFunction'  //isolate scope containing a reference to function
}

Note the use of the &operator to reference function in attribute.

Upvotes: 0

Related Questions