Stepan Suvorov
Stepan Suvorov

Reputation: 26176

What is the correct way to access controller that was required inside directive controller?

I have a directive with require property:

require: '^testBox'

now I want to get testBox controller inside controller of my directive. How should I do it?

I was trying to do so:

controller: function(){
  this.testBox.user
}

but looks like it does not work. It's clear for me how to get required controller inside link function. But is there a way to get it inside controller without using link?

Code on plunker.

Upvotes: 3

Views: 372

Answers (2)

LordTribual
LordTribual

Reputation: 4249

This is still an open issue. So at the moment you can not just inject the required controller into your directive controller. I have updated your Plunker. It's definitely a bit hacky but the problem is; You cannot expose the TextBoxCtrl to the UserCtrl in either the pre or post link function because the controller gets executed first. So my idea is to use a watcher to observe a scope varibale called textBox. Once the value is defined I declare a variable on the UserCtrl and remove the watcher. Now you can simply use it in your template like so:

{{ user.textBox.name }}

Here is the code for the link function and the controller of the user directive:

link: function($scope, $element, $attrs, ctrl) {
  $scope.textBox = ctrl
},
controller: function($scope) {
  var vm = this;

  var watcher = $scope.$watch('textBox', function(newVal) {
    if(newVal) {
      vm.textBox = newVal;
      watcher();
    }
  });
}

However, you can also go with a link function instead. The required controller will be injected as the fourth parameter.

Upvotes: 2

Nat Wallbank
Nat Wallbank

Reputation: 1457

When you use controllerAs it's just added as a property of the underlying scope object (using the name you've defined). Knowing this, you can attach the parent controller instance as a property of your child controller instance as follows:

    function exampleDirective() {
        return {            
            require: '^testBox',
            link: function (scope, element, attrs, testBox) {
                scope.example.testBox = testBox;
            },
            controllerAs: 'example',
            controller: function() {
                // silly example, but you get the idea!
                this.user = this.testBox.user;
            }
        }
    };

Upvotes: 0

Related Questions