For example:
$stateProvider
.state('external', {
url: 'http://www.google.com',
})
url assumes that this is an internal state. I want it to be like href or something to that effect.
I have a navigation structure that will build from the ui-routes and I have a need for a link to go to an external link. Not necessarily just google, that's only an example.
Not looking for it in a link or as $state.href('http://www.google.com'). Need it declaratively in the routes config.
Angular-ui-router doesn't support external URL, you need redirect the user using either $location.url()
or $window.open()
I would suggest you to use $window.open('http://www.google.com', '_self')
which will open URL on the same page.
Update
You can also customize ui-router
by adding parameter external
, it can be true
/false
.
$stateProvider
.state('external', {
url: 'http://www.google.com',
external: true
})
Then configure $stateChangeStart
in your state & handle redirection part there.
Run Block
myapp.run(function($rootScope, $window) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
if (toState.external) {
event.preventDefault();
$window.open(toState.url, '_self');
}
});
})
Sample Plunkr
Note: Open Plunkr in a new window in order to make it working, because google doesn't get open in iFrame due to some security reason.
You could use the onEnter
callback:
$stateProvider
.state('external', {
onEnter: function($window) {
$window.open('http://www.google.com', '_self');
}
});
Edit
Building on pankajparkar's answer, as I said I think you should avoid overriding an existing param name. ui-router put a great deal of effort to distinguish between states and url, so using both url
and externalUrl
could make sense...
So, I would implement an externalUrl
param like so:
myApp.run(function($rootScope, $window) {
$rootScope.$on(
'$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
if (toState.externalUrl) {
event.preventDefault();
$window.open(toState.externalUrl, '_self');
}
}
);
});
And use it like so, with or without internal url:
$stateProvider.state('external', {
// option url for sref
// url: '/to-google',
externalUrl: 'http://www.google.com'
});
As mentioned in angular.js link behaviour - disable deep linking for specific URLs you need just to use
<a href="newlink" target="_self">link to external</a>
this will disable angularJS routing on a specific desired link.
I transformed the accepted answer into one that assumes the latest version of AngularJS (currently 1.6), ui-router 1.x, Webpack 2 with Babel transpilation and the ng-annotate plugin for Babel.
.run(($transitions, $window) => {
'ngInject'
$transitions.onStart({
to: (state) => state.external === true && state.url
}, ($transition) => {
const to = $transition.to()
$window.open(to.url, to.target || '_self')
return false
})
})
And here's how the state may be configured:
.config(($stateProvider) => {
'ngInject'
$stateProvider
.state({
name: 'there',
url:'https://google.com',
external: true,
target: '_blank'
})
})
Usage:
<a ui-sref="there">To Google</a>
The original answer is deprecated and disabled by default in UI Router, you may wish to explore implementing it using transition hooks
.state("mystate", {
externalUrl: 'https://google.com'
})
then:
myApp.run(['$transitions', '$window', ($transitions, $window) => {
$transitions.onEnter({}, function (transition) {
const toState = transition.to();
if (toState.externalUrl) {
$window.open(toState.externalUrl, '_self');
return false;
}
return true;
});
}]
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With