1

I have a problem where it seems the angular a directive is activated on a elements despite them having a href or ng-href attribute. This causes angular to event.preventDefault() any clicks on these links when rendered.

The template I'm rendering is rendered inside a ng-include like directive. Which in turn is rendered in another directive.

The ng-include directive.

/*
* Use this when you need to include a view but want the scope to be transcluded.
*/
directiveModule.directive('rlInclude', [
  '$compile',
  '$templateRequest',
function (
  $compile,
  $templateRequest,
  $sce
) {
  'use strict';
  return {
    restrict: 'EA',
    transclude: true,
    link: function($scope, elem, attrs){
      var templateUrl = attrs.src;
      $scope.$watch(templateUrl, function(){
        $templateRequest(arguments[0],false).then(function(html){
          var template = angular.element(html);
          elem.html(template);
          $compile(elem.contents())($scope);
        });
      }, true);
    }
  }
}]);

When rendering the following template inside this directive the anchors are not clickable.

<div class="row">
  <div class="col-xs-2">
    <ul class="panel-header-links pull-right ">
      <li ng-click="change()">
        <a ng-href="{{'#/print/history/' + plan.id}}" class="nav-route cursor-pointer" target="history" >
          <span class="glyphicon glyphicon-print"></span>
          <span ng-bind="'PRINT' | translate"></span>
        </a>
      </li>
    </ul>
  </div>
</div>

All variables are inherited from the transcluded scope and the template is rendered correctly apart from the anchors that are not clickable even though they contain the correct information.

What I want is a way to avoid this. I could use the $route provider to solve this by putting an on-click on the anchors but since this component is supposed to be used by others I would prefer to solve this the correct way once and for all.

My Angular version is 1.5.4 My JQuery version is 2.2.3

Update

It seems the error some how is related to this code some how attaching an onClick handler twice to the anchor.

var htmlAnchorDirective = valueFn({
  restrict: 'E',
  compile: function(element, attr) {
    if (!attr.href && !attr.xlinkHref) {
      return function(scope, element) {
        // If the linked element is not an anchor tag anymore, do nothing
        if (element[0].nodeName.toLowerCase() !== 'a') return;

        // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.
        var href = toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?
                   'xlink:href' : 'href';
        element.on('click', function(event) {
          // if we have no href url, then don't navigate anywhere.
          if (!element.attr(href)) {
            event.preventDefault();
          }
        });
      };
    }
  }
});

When clicking the link the on click handler is fired twice. The first time element.attr(href) is true and the second time it is not. And that prevents the launching of the window.

If I make the second time pass the check by entering a href I'm correctly redirected.

1 Answer 1

1

I have solved this problem. The problem was that higher up in the compiled hierarchy there was a parent anchor that my directive was inserted in to. This part of the code was not touched by my change so It was quite hard to debug. The structure that could be represented like this.

<a id="parentWithoutHref">
  <directive>
    <...>
      <a id="theBrokenLink" href="url" />
    </...>
  </directive>
</a>

What happens is the event correctly bubbles after passing the first angular anchor directive check and stops at the second a tag which does not have a href attribute. It is easily solved by replacing the anchor, that should not have been an anchor in the first place, with a span or div.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.