Sangwoo Han Sangwoo Han - 5 months ago 18
Javascript Question

'require' in a subdirective depending on parent directive in AngularJS

I am trying to construct a sub directive which will later be used in multiple directives.

These parent directives have the same controller that provides some methods with which I want to update things in the scope of these directives :

(may use different controllers later but with these same common methods)

myApp
.controller('SomeCommonController', function() {
this.someMethod = function(data) {
// do something for updating scope variables
}
...
return this;
})
.directive('myDir1', function() {
return {
controller: 'SomeCommonController',
template : '<sub-dir ng-repeat="sth in aList" data="sth"></sub-dir>',
...
}
})
.directive('myDir2', function() {
return {
controller: 'SomeCommonController',
template : 'Something Different with calling <sub-dir data="otherData"></sub-dir>',
...
}
})
.directive('subDir', function() {
return {
scope: { data : "=" }
require: "^something", // parent directive
template: '<button ng-click="someMethod(data);"></button>'
link: function(scope, elem, attrs, parentDirectiveCtrl) {
scope.someMethod = function(data) {
parentDirectiveCtrl.someMethod(data);
};
},
...
}
})


Is there a way to require only the controller of the caller directive? Or is there a better way to achieve the same behavior?

Answer

I don't think so there is any way to find who is parent controller dynamically (I mean to say parent directive)

I'd suggest you to use require with array that means mention your require field in array, like here require would require: ['?^^myDir1', '?^^myDire2'] then inside link function 4th parameter is of controller, if you ctrl[0] you could get controller of myDir1 & if you do ctrl[1] then you will get controller of myDir2

You must use ?^^ because there could be one of them would not present in parent of directive

.directive('subDir', function() {
    return {
        scope: { data: "=" },
        require: ['?^^myDir1', '?^^myDir2'],  // parent directive
        template: '<button ng-click="someMethod(data);"></button>'
        link: function(scope, elem, attrs, parentDirectiveCtrl) {
            if(parentDirectiveCtrl[0])
              console.log('Parent controller is myDir1')
            if(parentDirectiveCtrl[1])
              console.log('Parent controller is myDir2')
            //whenever you want to call method of parent directive 
            //then you should use either parentDirectiveCtrl[0] for myDir1
            //or parentDirectiveCtrl[1] for myDir2
            scope.someMethod = function(data) {
                parentDirectiveCtrl[0].someMethod(data);
            };
        },
           ...
    }
})