Sam
Sam

Reputation: 1314

Access controller from a directive within a directive that has isolated scope

I'm just starting out with angularJS, and I've having a bit of an issue getting my head around scoping with directives and controllers.

In the example I've linked to below, I have a set of two directives; one attribute directive (showMessage) and one element directive (parentDirective).

http://jsfiddle.net/ejSxM/1/

I'd like to use showMessage as a behaviour, so that when an element is clicked, it fires a function in the controller. This works fine on normal html elements, but when I apply it to my parentDirective, showMessage takes the scope of the parentDirective, and not the controller.

This can be demonstrated in the attached example. When clicking on "I'm by myself", the directive has the scope of the controller, so the showMessage function in the controller scope calls fine. When Clicking on "I'm a directive" however, the directive now has the scope of the parent directive, and flags an error.

Is there a way that I can access the controller scope from the nested directive, even when the parent directive has an isolated scope?

Upvotes: 2

Views: 1558

Answers (2)

bbs
bbs

Reputation: 2022

You can set a controller for a directive.

controller - Controller constructor function. The controller is instantiated 
before the pre-linking phase and it is shared with other directives if they 
request it by name (see require attribute).
This allows the directives to communicate with each other and augment each other's 
behavior. The controller is injectable with the following locals:
$scope - Current scope associated with the element
$element - Current element
$attrs - Current attributes obeject for the element
$transclude - A transclude linking function pre-bound to the correct transclusion
scope:     
function(cloneLinkingFn).

http://docs.angularjs.org/guide/directive

Upvotes: 1

Anders Ekdahl
Anders Ekdahl

Reputation: 22933

You can pass in expressions to your directive like this: <my-directive onsomeevent="functionInMyController()"></my-directive>

And then in your directive:

...
scope: {
    onevent: '&onsomeevent'
},
link: function() {
    element.bind('click',function () {
       scope.onevent(); 
    });
}
...

That is, you bind the expression from the onsomeevent argument so that you can execute it inside your directive without knowing what the expression is. The expression is executed on the parent scope, so functionInMyController needs to be defined in the parent scope. You can also pass in variables from your linking function to that expression which you can find an example of here (in the scope section) directives.

Upvotes: 4

Related Questions