How can I expose a method from a directive? I know that I should use attributes for data, but I really want to expose behavior, not data. Something that the parent controller can call.
Let's say my DOM looks like:
<div ng-app="main"> <div ng-controller="MyCtrl"> <button ng-click="call()" >Call</button> <div id="container" my-directive> </div> </div> </div>
JavaScript:
angular.module("main", []).controller("MyCtrl", function($scope) { $scope.call = function() { $scope.myfn(); }; }).directive("myDirective", function() { return { // scope: {}, controller: function($scope) { $scope.myfn = function() { console.log("myfn called"); } } }; });
jsFiddle: http://jsfiddle.net/5gDjQ/7/
If the scope
is commented out (i.e. the directive does not have isolated scope), it works just fine. When I press the button, myfn
is called and logs to console.
As soon as I uncomment scope
, it doesn't work. myfn
is defined on child scope and not easily available to the parent.
In my case I think that polluting the parent scope is a bad idea and I would really like to avoid it.
So, how can I expose a function from directive to the parent controller? Or: How can I invoke a method on directive from parent controller?
An Isolated scope property can be bind with DOM attributes. Interpolate or attribute sets up a one-way data binding from the Parent scope to the Isolated Scope of Directive. It means if Parent scope does any changes then changes will be reflected to the Isolated scope of Directive.
Isolated scope directive is a scope that does not inherit from the parent and exist on its own. Scenario: Lets create a very simple directive which will show the object from the parent controller. var demoApp = angular.module('demoApp', []); demoApp.directive('myDirective', function() {
The directive scope uses prefixes to achieve that. Using prefixes helps establish a two-way or one-way binding between parent and directive scopes, and also make calls to parent scope methods. To access any data in the parent scope requires passing the data at two places – the directive scope and the directive tag.
You can do this with an isolated scope by setting up a variable in the scope that's two-way bound to the controller (using '='). In your directive you can then assign the function to that variable, and angular will use the binding to find the corresponding variable in your controller. That variable will point to a function that your controller can call.
http://jsfiddle.net/GWCCr/
html: Note the new attrib:
<div ng-app="main"> <div ng-controller="MyCtrl"> <button ng-click="call()" >Call</button> <div id="container" my-directive my-fn="fnInCtrl"> </div> </div> </div>
js:
angular.module("main", []).controller("MyCtrl", function($scope) { $scope.call = function() { $scope.fnInCtrl(); }; }).directive("myDirective", function() { return { scope: { myFn: '=' }, controller: function($scope) { $scope.myFn = function() { console.log("myfn called"); } } }; });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With