This is my main app (app.js)
(function(ng, module) {
module.config(['$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("app");
$stateProvider.state('login', {
url: 'login',
templateUrl: '/assets/templates/pages/login.html'
}).state('root', {
url: '',
templateUrl: '/assets/templates/pages/index.html'
});
}]);
}) (angular, angular.module('myapp', ['ui.router', 'myapp.submodule']));
This is the submodule (submodule.js)
(function(ng, module) {
module.config(['$stateProvider', function($stateProvider){
$stateProvider.state('root.substate', {
url: 'todo/{type}',
templateUrl: '/assets/app/todo/todo.html',
controller: function($stateParams, $scope) {
// Do stuff.
}
});
}]);
}) (angular, angular.module('myapp.submodule', ['ui.router']));
The expected behaviour would be
- redirect to "app" url when no matching route is found
- activate the "root" state on root url
- activate the "root.substate" state on /todo url
This is working fine.
However, if i do refresh the page, the state is not activated and i'm sent back to "app". Why?
This is my main app (app.js)
(function(ng, module) {
module.config(['$stateProvider', '$urlRouterProvider', function( $stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("app");
$stateProvider.state('login', {
url: 'login',
templateUrl: '/assets/templates/pages/login.html'
}).state('root', {
url: '',
templateUrl: '/assets/templates/pages/index.html'
});
}]);
}) (angular, angular.module('myapp', ['ui.router', 'myapp.submodule']));
This is the submodule (submodule.js)
(function(ng, module) {
module.config(['$stateProvider', function($stateProvider){
$stateProvider.state('root.substate', {
url: 'todo/{type}',
templateUrl: '/assets/app/todo/todo.html',
controller: function($stateParams, $scope) {
// Do stuff.
}
});
}]);
}) (angular, angular.module('myapp.submodule', ['ui.router']));
The expected behaviour would be
- redirect to "app" url when no matching route is found
- activate the "root" state on root url
- activate the "root.substate" state on /todo url
This is working fine.
However, if i do refresh the page, the state is not activated and i'm sent back to "app". Why?
Share Improve this question asked Feb 6, 2015 at 13:31 brazorfbrazorf 1,9612 gold badges32 silver badges55 bronze badges 5-
1
Maybe not the real issue, but I would for sure start any url with
/
-url: '/todo/{type}'
– Radim Köhler Commented Feb 6, 2015 at 13:34 - I'm still testing, but it seems that the leading slash may be the problem. – brazorf Commented Feb 6, 2015 at 14:37
-
Do you know why? Simply, there must be some way how to clearly define where the state url starts. Your mapping of url says:
domain/applogin
in fact... and I suggest:domain/app/login
. so no slash ... big issues for the engine, if you know what I mean – Radim Köhler Commented Feb 6, 2015 at 14:38 - Uhm i'm still confused. The leading slash on login and root states fixes them. The nested root.substate state works fine without the leading slash, and it's buggy with the leading slash. Buggy = refresh leads to unresolved route. Edit: Buggy = url it's rendered as foo.bar/#//todo (double slash). I think i'm missing something about url generation – brazorf Commented Feb 6, 2015 at 14:41
- Will try to show you how to in answer.. give me sec – Radim Köhler Commented Feb 6, 2015 at 14:43
2 Answers
Reset to default 7We have two root states (no parent) states. These should be either having no url, or it should start with some unique sign - the best choice would always with (URI spec) be a /
:
// domain/app/login - easy to find
.state('login', {
url: 'login',
...
})
// no def === domain/app
.state('root', {
url: '',
...
});
Now, let's use some url
even for our 'root'
state :
// domain/app/
.state('root', {
url: '/',
...
});
That mans, that our child 'root.substate' will also contain the parent url
part. So if we would use this
// this is a child and its url will be in fact: domain/app//todo/sometype
.state('root.substate', {
url: '/todo/{type}',
...
});
See, that this way, our url will now for child contain // (double slash)
To avoid that, we can use UI-Router feature '^'
// this stat will not use the parent part
// this will work domain/app/todo/sometype
.state('root.substate', {
url: '^/todo/{type}',
...
});
Check the doc:
Absolute Routes (^)If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '^/list',
...
});
I know a lot of time left. But about issue with refreshing. If you want to stay on the same url address as before refreshing you should add next:
angular.module('app').run(['$state', '$stateParams', function($state, $stateParams) {
//this solves page refresh and getting back to state
}]);
like mentioned here in pre-last answer