Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular Ui-router link out of app but in the same domain

I'm trying to use ui-router in my angular app.

My base url is "/segments" and I use base tag to define it.

<base href="/segments" />

Here is my routing config:

var base = "/segments"

$stateProvider
  .state('list', {
    url: base,
    controller: 'FilterLestCtrl',
    templateUrl: '/segments/partial?partial=list'
  })

  .state('new', {
    url: base + '/new',
    data: {
      mode: 'new'
    },
    controller: 'SegmentFormCtrl',
    templateUrl: '/segments/partial?partial=edit'
  })

  .state('edit', {
    url: base + '/:id/edit',
    data: {
      mode: 'edit'
    },
    controller: 'SegmentFormCtrl',
    templateUrl: '/segments/partial?partial=edit'
  });

$locationProvider.html5Mode(true).hashPrefix('!');

When I click to link tag I can't get out from my app to other resource on my site, i.e. I click to tag

<a class="" href="/widgets">Widgets</a>

and then url changing and nothing happened.

Question: How handle external link to other pages on site with ui-router?

like image 989
Anton Rodin Avatar asked Jan 07 '14 19:01

Anton Rodin


4 Answers

This might be helpful: angular.js link behaviour - disable deep linking for specific URLs

To summarize, you can tell Angular to ignore a link for routing purposes by adding target="_self" to it. This will allow the browser to handle the link unencumbered by Angular. For example:

<a href="/my-non-angular-link" target="_self">My Non-Angular Link</a>

This approach works for links that you know beforehand should not be handled by Angular.

like image 135
Heston Liebowitz Avatar answered Sep 25 '22 13:09

Heston Liebowitz


What's happening is ui-router is triggering an otherwise() response for the URL, because it failed to match the URL to the list of known states.

You see the URL update in the browser, but nothing happens because the error was unhandled in the Javascript code.

You can add a handler for unmatched states like this.

var stateHandler = function($urlRouterProvider)
{
    $urlRouterProvider.otherwise(function($injector, $location)
     {
         window.location = $location.absUrl();
     });
};

YourAngularApp.config(['$urlRouterProvider',stateHandler]);

When ui-router fails to match a state it will call the otherwise() callback. You can then manually force the browser to go to that URL.

EDIT: Warning, this will cause an infinite redirect loop if the URL is an Angular path with a bad route.

like image 30
Reactgular Avatar answered Sep 23 '22 13:09

Reactgular


On a single element, you can just do:

<a href="some/url" ng-click="$event.stopPropagation()">A link outside of the app</a>
like image 6
mattwad Avatar answered Sep 24 '22 13:09

mattwad


First point is: angular handle all click on a element by default and trying resolve value of href attribute via routing system. Information about it is here Angular docs

Second point is: I used wrong base url. Instead of using /segments I should use /segments/. Slash at end of string has a very significant meaning! Angular skip links which isn't on my base (/segments/).

Other solution described here. But I suggest to use

$rootElement.off('click');

in some controller, not in run function. In my case run function has been called before angular binds click handle.

So good luck to everybody! :)

like image 3
Anton Rodin Avatar answered Sep 25 '22 13:09

Anton Rodin