Reputation: 11203
I'm aware how I can get parent's directive
controller in the child directive's link
function.
However, I'd prefer to avoid using link
function (and $scope
all-together) and have all my code under the controller
function of the directive.
angular.directive('parent', function(){
return {
templateUrl: '/parent.html',
scope: true,
bindToController: true,
controllerAs: 'parentCtrl',
controller: function(){
this.coolFunction = function(){
console.log('cool');
}
}
}
});
angular.directive('child', function(){
return {
templateUrl: '/child.html',
require: '^parent',
scope: true,
bindToController: true,
controllerAs: 'childCtrl',
controller: function() {
// I want to run coolFunction here.
// How do I do it?
}
}
});
Any help is appreciated!
Upvotes: 7
Views: 2135
Reputation: 4595
var parentForm = $element.inheritedData('$formController') || ....
var parentForm = $element.controller('form')
Upvotes: 0
Reputation: 916
You could inject '$element' into the controller and access the parent controller like -
controller: ($element) ->
var parentCtrl = $element.parent().controller('parent');
parentCtrl.coolFunction();
//..........
//..........
This may not be the most transparent way of accessing 'any' parent controller because it requires the specific name of the directive and it is jqlite and not pure Angular.
Found this thread useful - How to access parent directive's controller by requiring it recursively?
EDIT: Thanks to @Dmitry for figuring out that angular doesn't need '.parent' to get the controller. Updated code -
controller: ($element) ->
var parentCtrl = $element.controller('parent');
parentCtrl.coolFunction();
//..........
Upvotes: 1
Reputation: 222493
The proper pattern for that would be
app.directive('child', function(){
return {
templateUrl: '/child.html',
require: ['child', '^parent'],
scope: true,
bindToController: true,
controllerAs: 'childCtrl',
controller: function() {
this.coolFunction = function () {
this._parent.coolFunction();
}
},
link: function (scope, element, attrs, ctrls) {
var childCtrl = ctrls[0];
var parentCtrl = ctrls[1];
childCtrl._parent = parentCtrl;
}
}
});
The bad thing is that _parent
is being exposed to scope with controllerAs
, but it will rarely be a problem.
Notice that you won't have access to parent controller from child until link
glues them together. Which is fine as long as you use parent controller in child methods.
Controller provides methods and initial properties to view model (and it does it cleaner with controllerAs), link glues the stuff, that's how directives work.
Both $scope
and link
have their purposes in Angular 1.x and are indispensable even with latest community developments. Banishing them for no valid reason is overzealous and may lead to bad design solutions. The absence of 'link' and 'scope' words in code won't help to make the app easier to port to 2.x. Though learning Angular 2 now and developing proper habits for 1.x will.
Upvotes: 4