Ad

Defining My Own 'require' On A Directive, But Throw Error - AngularJs

- 1 answer

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?

Ad

Answer

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.

Ad
source: stackoverflow.com
Ad