0

How do I get a native angularjs state change for an anchor link that has been $compile()'d?

Updates: 2018-06-18 - Still hitting this problem. Been searching like crazy trying different things and still nothing; 2018-05-28 - I'm still having this issue and don't really have any leads. I've tried many variations and the problem of dynamically linking text with native angularjs state changes remains.

I have some untrusted text which I pass through a service that links #hashtags and @mentiontags. I use $sce.trustAsHtml() and I assign the linkified text back to a $scope.text variable which I use in the view. It works, I can see and click on the link, but instead of a state change I'm getting a full browser url load.

I've checked the state change when done normally through a view and it works.

So, for example:

  1. I have some untrusted text: Hey, @user, you'll love this!
  2. I pass it through the linking function and get this: Hey, <a ui-sref="user">@user</a>, you'll love this!"
  3. I $compile() that to get states linked up and when inspected in the DOM, it looks like this: Hey, <a ui-sref="user" href="/user">@user</a>, you'll love this!

But when I click the link it's not an angularjs state change, it's a full browser url reload.

Any ideas?

Thanks,

Shovas
  • 215
  • 1
  • 9
  • What do you mean by `not an angularjs state change`? Do you mean `href="#!user"`? – RaphaMex Jun 18 '18 at 22:54
  • I mean the browser does a full http request rather than angularjs doing native state change as if I had a foo or $state.go('foo') anywhere else normally. These work. It's only when I'm in this dynamic situation where it doesn't. – Shovas Jun 19 '18 at 15:51

2 Answers2

1

Not sure what your problem is. I would expect that, if you click a link, you get out of your page. A trick could be to open link in new tab with target:

<a ui-sref="user" href="/user" target="_blank">@user</a>

However, if it comes from $compile, here is a sample code I use that works:

link: function ($scope, $element, $attrs) {
    $scope.x = "x variable";
    var html = 'your html here like in a template: $scope.x = {{x}}';
    var e = $compile(html)($scope);
    $element.replaceWith(e);
}

Hope it helps!

RaphaMex
  • 2,781
  • 1
  • 14
  • 30
  • Thanks. Maybe this is what I'm not understanding: I don't see why I would use the link function in my case. In my case, I have a directive, it gets data with an api call during init, compiles the link itself, and displays the directive's view. How would I even fit this link usage in with my directive? Do I need *another* directive just for that link so that I can get to use the link function? And it would be really nice to know why there's a difference with $compile using it inside or outside the link function. – Shovas Jun 21 '18 at 18:58
  • `$compile` is for advanced use of angularjs. So I recommend you do not use it. The `link` function I put here is an angular property of your directive. It is no related to a hyperlink. Can you show what you have tried? I cannot help you more without a minimal example of your code reproducing your issue. – RaphaMex Jun 21 '18 at 20:36
  • Thanks for helping. Turns out I was using ng-bind-html which wasn't processing directives. I found that out reading a related question. I've posted an answer with details. – Shovas Jun 22 '18 at 20:01
0

AngularJS ng-bind-html="html" was not processing embedded directives in the "html" (although somehow it was generating accurate hrefs from ui-sefs...).

Based on this question's answer I was able to get the embedded directives to execute.

The solution was to provide a "compile" directive which, while acting like ng-bind-html, would actually fully compile and process directives. More details are in the linked question.

Shovas
  • 215
  • 1
  • 9