Question

I had such html code

<a href="#" id="someLink">
    <i class="someClass"></i><span>Some span text</span>
</a>
<div id="dependsOnSomeLink">
    <!-- something here -->
</div>

that I wanted to separate into directives in AngularJS. The logic behind it was, that contents of div is hidden by default and is shown by click on a element.

I wanted to separate that into two directives like that:

angular.module('someModule', [])
  .directive('prAbc', function($log) {
    return {
      require: 'prDef',
      restrict: 'E',
      template: '<a href="#" id="someLink"><i class="someClass"></i><span>Some span text</span></a>',
      controller: function($scope, $element, $attrs, $transclude) {
        // do the harlem share <-- here
      },
      link: function(scope, iElement, iAttrs, prDef, transcludeFn) {
        iElement.bind('click', function() {
          prDef.toggleDependentBlock();
        });
      }
    };
  })
  .directive('prDef', function($log)
  {
    return {
      restrict: 'E',
      template: '<div id="dependsOnSomeLink"></div>',
      controller: function($scope, $element, $attrs, $transclude) {
        $scope.showDependentBlock = false;

        this.toggleDependentBlock = function() {
          $scope.showDependentBlock = false === $scope.showDependentBlock;
        };
      }
    };
  });

and later use it like that

<pr-abc></pr-abc>
<pr-def></pr-def>

But prDef is not defined when it is called from prAbc directive.

Était-ce utile?

La solution

require: 'prDef' works when prAbc and prDef are applied on the same DOM element, which is not your case.

What you may need is "parent" directive which will act as a router between the two communicating directives. prDef registers itself to the parent controller and prAbc calls the parent controller which, in turn, calls prDef.

Check out this plucker.

There are at least 3 other options to consider:

  1. Have the parent controller listen to specific events that prAbc emits and broadcasts them downwards, where prDef listens on.

  2. Have the parent controller pass callback functions ('&') to the child directives for registration and routing.

  3. All functions and data is defined on the parent and passed to child directives through binding or prototypal inheritance (essentially, ruin your design :P).

For all 3 options, the parent controller does not have to be defined in a directive, it can be any controller which you apply like:

<div ng-contoller="ParentCtrl">
    <pr-abc></pr-abc>
    <pr-def></pr-def>
</div>

Your example does not provide enough context to reason which option is the best, but I think the parent directive should be the preferred way to go.

If it helps, checkout how ui-bootstrap's tabs and accordion are implemented. It's a very helpfull example of collaborating, still decoupled, set of directives.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top