0

I have two angularjs directives (extWindow and taskBar) and want to inject taskBar's controller into extWindow in order to access it's scope. Because they don't share the same scope I used

require : '^$directive'

syntax to include it. Doing so I could get rid of the error 'Controller 'taskBar', required by directive 'extWindow', can't be found!' but TaskBarCtrl is still undefined in link(..) method of the extWindow directive.

Any suggestions how to fix it?

var mod = angular.module('ui', [])
.directive('taskBar', function() {

    var link = function(scope, el, attrs) { 
        $(el).css('display', 'block');
        $(scope.titles).each(function(i,t) {
            el.append('<span>' + t + '</span>')
        });
    };

    return {
        scope: {},
        restrict : 'E',
        controller: function($scope, $element, $attrs) {

            $scope.titles = [];

            this.addTitle = function(title) {               
                $scope.titles.push(w);
            };

            this.removeTitle = function(title) {
                $scope.titles = jQuery.grep(function(n,i) {
                    return title != n;
                });
            }
        },
        link: link
    };
}).directive('extWindow', function() {  

    return {
        scope: {},
        require: '^?taskBar',
        restrict: 'E',
        transclude: true,
        template: '<div class="ui-window">\
            <div class="ui-window-header"><span>{{windowTitle}}</span><div class="ui-window-close" ng-click="close()">X</div></div>\
            <div class="ui-window-content" ng-transclude></div>\
            </div>',
        link: function(scope, element, attrs, taskBarCtrl) {
            scope.windowTitle = attrs['windowTitle'];   
            scope.close = function() {
                $(element).css('display', 'none');
            }
            //taskBarCtrl is not recognized!!!
            taskBarCtrl.addTitle(scope.windowTitle);
        }
    }
});

http://jsfiddle.net/wa9fs2nm/

Thank you. golbie.

1
  • When you use require with the ^ symbol, aren't you effectively saying that the taskBar directive must be the parent of extWindow? I've made plenty of directives like that with no problem. You'd need to transclude the parent directive to make it work though. Commented Oct 28, 2014 at 23:25

1 Answer 1

1

If you have a controller for your parent directive and you need something like.

this.scope = $scope;
this.attrs = $attrs;

And in your in you link function for the child you need something like

var Ctrl = ctrl || scope.$parent.tBarCtrl;

Here's a Plunker

Sign up to request clarification or add additional context in comments.

4 Comments

hi dylan, thank you for this beautiful and working example but I think it needs to be discussed. Let me explain my findings.
The first thing I need is to define a controller in the module.This is then visible for the directive (at least for those defined in the same scope) and can be referenced by controller:'ctrl'.Now a second directive wants to use the controller of another directive by using require: '^?directivename'.Referencing it should also make available the controller in the link function. But controller is not available inside "yellow" directive.At the other hand "red" can access the controller but changes made there arent populated to the template.Thx.plnkr.co/edit/HOCi2QlFMA0P77w0OPWL
I finally managed the right solution.The mistake was that the second directive wasn't wrapped by the first one. As stated in the api docs '^?name' is looking for the directive at the parent level. Since both directives are siblings the directive isn't found and therefore taskBarCtrl is undefined. Another solution for the communication among directives could be passing external function of a controller to them (& operator). See this solution plnkr.co/edit/itEhaA5cfRpxylf6TMZ4?p=preview.
Yeah I guess I got a bit carried away with my example and didn't realize, it looks like my example relies on the main as parent and not the taskbar controller as I had thought.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.