0

Let us say I have this html:

<div ng-controller="MyCtrl">    
    <br>
    <my-directive my-name="name">Hello, {{name}}!</my-directive>
</div>

with this simple controller:

myApp.controller('MyCtrl', function ($scope) {
    $scope.name = 'Superhero';
});

And I have a directive in which I want to change the 'name' using require like this:

myApp.directive('myDirective', function($timeout) {
var controller = ['$scope', function ($scope) {
    $scope.name = "Steve";
}];
    return {
        restrict: 'EA',
        require: 'myName',
        controller: controller,
        link: function(scope, element, attrs, TheCtrl) {
            TheCtrl.$render = function() {
                $timeout(function() {
                    TheCtrl.$setViewValue('StackOverflow');  
                }, 2000);                
            };
        }
    };
});

But throws:

Error: No controller: myName

Here is the fiddle


But if I implement it using ng-model, works. Look here in this other fiddle

I have read that if you use 'require' in a directive, you need to have a controller for it.

So:

What I'm doing is wrong? It is not in this way? I need to do any other thing?

robe007
  • 3,523
  • 4
  • 33
  • 59
  • The error tells you what the problem is, myName is not a controller. Require is looking for a controller, and 'my-name' is simply an attribute you have defined on 'my-directive' – Brian Jan 22 '16 at 00:15
  • Explain what you expect this `require` to do? With the limited code shown it doesn't make sense to use it at all – charlietfl Jan 22 '16 at 00:20
  • @Brian Have you see the second fiddle? Compare both fiddle's, and then tell me again. `require: 'ngModel',` is a directive, that has it's own controller: [ngModel.NgModelController](https://docs.angularjs.org/api/ng/type/ngModel.NgModelController) – robe007 Jan 22 '16 at 00:21
  • @charlietfl I'm just practicing. I just want to know if I can use `require` inside a directive with my own attr (in this case my-name)? Or just only I can use `require` with `ng-model`? – robe007 Jan 22 '16 at 00:24
  • @charlietfl I think that `my-name` has to be a directive, as I read on the link I showed on my question. Is this true? – robe007 Jan 22 '16 at 00:25
  • 1
    no...`require` has nothing to do with attributes. Also `$setViewValue` has nothing to do with text...it is an `ng-model` method related to setting form control values – charlietfl Jan 22 '16 at 00:25
  • 1
    and yes... `my-name` would have to be a directive that has a controller. Lots of directives don't even use controllers – charlietfl Jan 22 '16 at 00:28
  • @charlietfl Well, I think I have to practice a little more. When I have an answer, I'll be back. – robe007 Jan 22 '16 at 00:30

1 Answers1

0

Well finally I got it.

Essencially what I'm trying to do is something called: 'Communication between directives using controllers'. I have found an article explaining this, and helped me a lot:

The view:

<div ng-controller="MyCtrl">
 <br>
 <my-directive my-name>Hello, {{name}}!</my-directive>
</div>

As you see above, there are two directives: my-directive and my-name. I will call inside my-directive a function from the controller of my-name directive using require.

myDirective:

myApp.directive('myDirective', function($timeout) {
 return {
  require: 'myName',
  link: function(scope, element, attrs, myNameCtrl) {
   $timeout(function() {
    myNameCtrl.setName("Steve");
   }, 9000);
  } // End of link
 }; // return
});

myName:

myApp.directive('myName', function($timeout) {
    var controller = ['$scope', function ($scope) {
        // As I tried, this function can be only accessed from 'link' inside this directive
        $scope.setName = function(name) {
            $scope.name = name;
            console.log("Inside $scope.setName defined in the directive myName");
        };

        // As I tried, this function can accessed from inside/outside of this directive
        this.setName = function(name) {
            $scope.name = name;
            console.log("Inside this.setName defined in the directive myName");
        };
    }];

    return {
        controller: controller,
        link: function(scope, element, attrs, localCtrl) {
            $timeout(function() {
                localCtrl.setName("Charles");
            }, 3000);
            $timeout(function() {
                scope.setName("David");
            }, 6000);
        } // End of link function
    };
});

Interesting and works like a charm. Here is the fiddle if you want to try it out.

Also, you can get communication between directives using events. Read this answer here on SO.

Community
  • 1
  • 1
robe007
  • 3,523
  • 4
  • 33
  • 59