Search code examples
javascriptangularjsangular-bootstrap

angular-bootstrap add new directive dosn't work


I want to create a new directive into ui.boostrap.accordion module to avoid accordion open click event.

I have the following code in another file.js:

angular.module('ui.bootstrap.accordion')
.directive('accordionGroupLazyOpen', function() {
  return {
    require: '^accordion',         
    restrict: 'EA',
    transclude: true,              
    replace: true,                
    templateUrl: function(element, attrs) {
      return attrs.templateUrl || 'template/accordion/accordion-group.html';
    },
    scope: {
      heading: '@',               
      isOpen: '=?',
      isDisabled: '=?'
    },
    controller: function() {
      this.setHeading = function(element) {
        this.heading = element;
      };
    },
    link: function(scope, element, attrs, accordionCtrl) {
      accordionCtrl.addGroup(scope);

      scope.openClass = attrs.openClass || 'panel-open';
      scope.panelClass = attrs.panelClass;
      scope.$watch('isOpen', function(value) {
        element.toggleClass(scope.openClass, value);
        if (value) {
          accordionCtrl.closeOthers(scope);
        }
      });

      scope.toggleOpen = function($event) {
      };
    }
  };
})

The problem is when I execute the app I get the following error:

Controller 'accordionGroup', required by directive 'accordionTransclude', can't be found!

Error link

Any ideas?


Solution

  • As I see from the source code ( maybe not your version but still the same):

    // Use in the accordion-group template to indicate where you want the heading to be transcluded
    // You must provide the property on the accordion-group controller that will hold the transcluded element
    .directive('uibAccordionTransclude', function() {
      return {
        require: '^uibAccordionGroup',  // <- look at this line in your version
        link: function(scope, element, attrs, controller) {
          scope.$watch(function() { return controller[attrs.uibAccordionTransclude]; }, function(heading) {
            if (heading) {
              element.find('span').html('');
              element.find('span').append(heading);
            }
          });
        }
      };
    

    So I guess it tries to find a parent directive in the view that matches accordionGroup but since you add the accordionGroupLazyOpen and not the accordionGroup it cannot find it.

    In the error page you provided states:

    This error occurs when HTML compiler tries to process a directive that specifies the require option in a directive definition, but the required directive controller is not present on the current DOM element (or its ancestor element, if ^ was specified).

    If you look in the accordion-group-template file you will see that the accordionTransclude directive gets called there.