1

I am using accordion directive in my template, and inside accordion i am adding attr ng-click on a element. When I click on that element it fires twice.

Fiddle : http://jsfiddle.net/Lvc0u55v/10071/

Code :

//accordion directive
.directive('simpleAccordion', function($compile, $timeout) {
    return {
        restrict: 'AEC',
        controller: function($scope) {
            $scope.current = null;
            $scope.height = [];
            $scope.zero = {
                height: 0
            };
            $scope.toggle = function(i) {
                $scope.current = $scope.current === i ? null : i;
            };
        },
        link: function(scope, el, attrs) {
          var itemSelector = '[item-selector]' || 'li',
              titleSelector = '[title-selector]' || 'h2',
              contentSelector = '[content-selector]' || 'div';
          $timeout(function(){
            var items = el[0].querySelectorAll(itemSelector);
            for (var i in items) {
              if (angular.isObject(items[i])) {
                var title = items[i].querySelectorAll(titleSelector)[0];
                var content = items[i].querySelectorAll(contentSelector)[0];
                scope.height.push({
                  'height': (content.offsetHeight + 10) + 'px'
                });
                angular.element(items[i]).addClass('item').attr({
                  'ng-class': '{\'open\':current == ' + i + '}'
                });
                angular.element(title).addClass('title').attr('ng-click', 'toggle(' + i + ')');
                angular.element(content).addClass('content').attr({
                  'ng-style': 'current == ' + i + '?height[' + i + ']:zero'
                });;

              }
            }
            $compile(angular.element(el).contents())(scope);
          });
        }
    }
})

Fiddle : http://jsfiddle.net/Lvc0u55v/10071/

Amit
  • 827
  • 10
  • 17

1 Answers1

1

By default angular compiles all content of your directive, so then you call compile in link function, ng-click will be compiled twice.

To prevent these behavior, protect your html from compiling by terminal and priority attrs, and compile it manually, excluding your directive by third argument(priority).

change directive definition to:

{
....
terminal: true,
priority: 1000
...
}

and call compile like: $compile(el, null, 1000);

Valery Kozlov
  • 1,557
  • 2
  • 11
  • 19
  • 3
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – ryanyuyu Sep 26 '16 at 13:01
  • is `priority` value `1000` is mandatory, if not then on which basics and how much we can set `priority` value. – Amit Sep 26 '16 at 13:12
  • each directive has priority in angular, default is 0, but some built-in directives have different priority. Angular start compiling directive from higher priority to lower. Capped by js number limitations. – Valery Kozlov Sep 26 '16 at 13:14
  • @ValeryKozlov Thanks for answer. – Amit Sep 26 '16 at 13:17