Reputation: 4501
I want to call a function defined in a directive, just the opposite of this stackoverflow question
I tried this but does not work.
app.directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
scope.someDirectiveFn = function(arg) {
return "in directive";
};
},
}
});
function MyCtrl($scope) {
alert($scope.someDirectiveFn());
}
Is that possible? how could I get it? is it a bad practice?
EDIT
I got this way:
.controller('MyCtrl', function($scope) {
alert($scope.func());
})
.directive('myDirective', function() {
return {
controller: function($scope, $element){
$scope.func = function() {
return "text";
};
}
}
});
Upvotes: 2
Views: 934
Reputation: 4115
You can use event system to achieve that.
First, emit a custom event on your scope with your parameters. Second, listen to the scope in your directive with angular $on method.
app.controller('MyCtrl', function($scope) {
$scope.invokeDirectiveMethod = function() {
$scope.$emit('invokeMyDirectiveMethod', 'myParameter');
};
})
.directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
var someDirectiveFn = function(event, arg) {
alert(arg + " in directive");
};
scope.$on('invokeMyDirectiveMethod', someDirectiveFn);
},
}
});
Here is a working plunker.
UPDATE
Based on your update, event communication does not fit your problem.
How about passing an object to directive using two way binding and defining someDirectiveFn in that object? This way you can pass arguments and return values from it.
app.controller('MyCtrl', function($scope) {
$scope.shareObject = {};
$scope.invokeDirectiveMethod = function() {
if (angular.isFunction($scope.shareObject.someDirectiveFn)) {
$scope.message = $scope.shareObject.someDirectiveFn('from controller');
}
};
})
.directive('myDirective', function() {
return {
scope: {
'shareObject': '='
},
link: function(scope, element, attrs) {
scope.shareObject.someDirectiveFn = function(arg) {
return arg + ' from parameter';
};
},
}
});
Updated plunker.
Upvotes: 3
Reputation: 1345
You didnt post your html code, so I assume that your custom directive is used IN MyCtrl
. This does not work because of when the functions are executed.
Controller functions are always executed before link functions.
Here is a cool article about the differences.
So if you want your controller to be able to invoke a function in the directive you can broadcast events (like in halilb's answer) or make the directive to listen to specific scope values, like this:
app.directive('myDirective', function() {
return {
link: function(scope, element, attrs) {
scope.$watch("message", function() { console.log(message); });
},
}
});
function MyCtrl($scope) {
$scope.message = "Hello Directive";
}
Upvotes: 1
Reputation: 796
I'm guessing you want to have a function that is shared between a directive and a controller lets say?
if thats the case how about creating a service and injecting the service into both directive and ctrl. This way you would only have to create it once.
app.service('sharedFucntionService', function() {
return {
someFn : function (arg) {
alert(arg + " in directive")
}
}
});
Injecting the service into a directive
app.directive('myDirective',function( sharedFucntionService){
return {
link: function (scope, element, attrs) {
// do something with sharedFucntionService
}
}
});
Inject the service into the controller as well function MyCtrl($scope, sharedFucntionService){ ...... }
Upvotes: 0