0

There is a similar question out there, but it only applies to hard-coded hrefs, not ones that are interpolated by angular. See Conditionally add target="_blank" to links with Angular JS

The solution I'm looking for is best illustrated by the following directive:

yourModule.directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      var a = elem[0];
      if (location.host.indexOf(a.hostname) !== 0)
        a.target = '_blank';
    }
  }
}

The problem is that the directive runs before angular has done any interpolation, and therefore all links appear relative. Is there a clean way to do this? I can't use mutation observers, because I must support IE9.

2 Answers 2

4

I would suggest to use 2 option that was already provided:

<a href="http://www.google.com" target="{{condition ? '_blank' : '_self'}}">Link</a>

and set condition variable in directive controller, depending on location.

If you provide sandbox for this issue it would be really helpful.

UPD: if you want to have more hacks you could you $timeout and wrap it there.

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

4 Comments

This would require adding markup to every link. I am looking for a solution that wouldn't require additional markup.
I got your point. But it's normal to add attribute otherwise it would be attribute directive. ".directive('a'," - look's like hack for me
I disagree that .directive('a')... would be a hack. It does exactly what I want it to do -- change the behavior of all links to open external hrefs in a new tab. It's the opposite of a hack IMO. It's elegant and totally self-contained.
I would say you extend element behaviour in non-declarative way. For me it's like extend/rewrite JS native object prototypes.
2

The solution ended up being quite simple. Angular provides a built-in way to observe attributes and react to changes:

yourModule.directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      attrs.observe('href', function(){
        var a = elem[0];
        if (location.host.indexOf(a.hostname) !== 0)
          a.target = '_blank';
      }
    }
  }
}

1 Comment

I hope you know that you replace the built-in a directive and lose its functionality.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.