I might be thinking about this completely backwards, but I'm trying to make three nested directives, lets call them: screen, component and widget. I want widget to be able to trigger some behavior in component, which in turn triggers some behavior in screen. So:
.directive('screen', function() {
return {
scope: true,
controller: function() {
this.doSomethingScreeny = function() {
alert("screeny!");
}
}
}
})
.directive('component', function() {
return {
scope: true,
controller: function() {
this.componentFunction = function() {
WHAT.doSomethingScreeny();
}
}
}
})
.directive('widget', function() {
return {
scope: true,
require: "^component",
link: function(scope, element, attrs, componentCtrl) {
scope.widgetIt = function() {
componentCtrl.componentFunction();
};
}
}
})
<div screen>
<div component>
<div widget>
<button ng-click="widgetIt()">Woo Hoo</button>
</div>
</div>
</div>
I can require parent components in a widget's link fn using require: "^component", but how do I further give components controller access to its containing screen?
What I need is the WHAT in component so when you click the widget's button it alerts "screeny!".
Thanks.
Here are two ways you could solve your problem:
scope: true, all scopes prototypically inherit. So if you define your methods on $scope instead of on this in the screen controller, then both component and widget will have access to function doSomethingScreeny.
component and require: '^screen'. In the link function, save the screenCtrl to a scope property, then you can access it in the directive's controller (inject $scope).
Most of this stuffs fails when you want to directly access properties or methods from the parent controller on controller creation. I found another solution by using dependency injection and using the $controller service.
.directive('screen', function ($controller) {
return {
require: '^parent',
scope: {},
link: function (scope, element, attr, controller) {
$controller('MyCtrl', {
$scope: scope,
$element: element,
$attr, attr,
controller: controller
});
}
}
})
.controller('MyCtrl, function ($scope, $element, $attr, controller) {});
This method is better testable and does not pollute your scope with unwanted controllers.