Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expose behavior from a directive with isolated scope?

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?

like image 648
Konrad Garus Avatar asked Apr 10 '13 19:04

Konrad Garus


People also ask

How can we isolate the scope of the directive?

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.

What is isolated scope?

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() {

What is directive scope?

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.


1 Answers

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");             }         }     }; }); 
like image 83
Roy Truelove Avatar answered Sep 23 '22 07:09

Roy Truelove