最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular JS - UI router page reload won't set the state - Stack Overflow

programmeradmin5浏览0评论

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
Add a ment  | 

2 Answers 2

Reset to default 7

We 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

发布评论

评论列表(0)

  1. 暂无评论