Angular-UI-Router with Html5Mode refresh page issu

2020-04-16 02:10发布

I have an app that uses angular-ui-router with html5mode(true). Everything seems to work fine when running and routing to other states.

My default state is app/calendar which is set during module.run()

But when i refresh the page while i'm currently in other routes(lets say app/profile) it takes me back to app/calendar.

Debugging i noticed that the $state.current is always empty after i refresh the page

Object {name: "", url: "^", views: null, abstract: true}

if only the $state.current has value i can just transistion to the current state.

Is there anything that i am missing?

Hopefully someone can help.

My server routing looks like

app.get('/:var(/|app/calendar|app/customers|app/profile|app/settings)?', function(req, res) {
    res.sendFile('/app/main/main.html',{ root: '../Appt/public' });
});

i'm always serving the same file.

and my front-end state configuration

(
    function()
    {
        angular.module('Appt.Main').config(['$stateProvider','$locationProvider',function($stateProvider,$locationProvider)
        {
            $locationProvider.html5Mode(true);

            var calendar = {
                    name: 'calendar',
                    url: 'app/calendar',
                    controller: 'Appt.Main.CalendarController',
                    controllerAs: 'calendar',
                    templateUrl: '/app/main/calendar/calendar.html'
                },
                customers = {
                    name: 'customers',
                    url: 'app/customers',
                    controller : 'Appt.Main.CustomersController',
                    controllerAs : 'customers',
                    templateUrl : '/app/main/customers/customers.html'
                },
                profile = {
                    name: 'profile',
                    url: 'app/profile',
                    controller : 'Appt.Main.ProfileController',
                    controllerAs : 'profile',
                    templateUrl : '/app/main/profile/profile.html'
                },
                settings = {
                    name: 'settings',
                    url: 'app/settings',
                    controller : 'Appt.Main.SettingsController',
                    controllerAs : 'settings',
                    templateUrl : '/app/main/settings/settings.html'
                };


            $stateProvider.state(calendar);
            $stateProvider.state(customers);
            $stateProvider.state(profile);
            $stateProvider.state(settings);

        }]);

    }
)();

My module.run

(
    function()
    {
        'use strict';

        angular.module('Appt.Main',['ngRoute','ui.router','Appt.Directives'])
            .run(['$state','$stateParams', function ($state,$stateParams) {
                console.log('Appt.Main is now running')


                console.log($state.current);
                console.log($stateParams);

                $state.transitionTo('calendar');


            }])
    }
)();

2条回答
戒情不戒烟
2楼-- · 2020-04-16 02:48

I'm not sure if this is going to solve your problem, but I had a very similar problem. First thing I had to do to use html5mode was to use a rewrite property so the app would reload from the index file when i refresh the page, no matter what $state I'm. This is the code I´m using, but it may be different, depending on the serverside you are using.

<IfModule mod_rewrite.c>
    RewriteEngine On
    #RewriteBase /relative/web/path/

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^(.+) - [PT,L]

    RewriteCond %{REQUEST_URI} !=/favicon.ico
    RewriteRule ^(.*) index.html

    RewriteCond %{HTTP:Authorization}  !^$
    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
</IfModule>

You can read more here, in the docs from ui-router

Also, you'd better set a base or not use a base for your app.

You either insert <base href="/" >inside your head tag (or other base folder, depending on your structure).

Or you can use:

$locationProvider.html5Mode({
    enabled: true,
    requireBase: false
});

So you don't have to use a base.

Also, you don't need a .run to define a default state, ui-router can do it with $urlRouterProvider.when or $urlRouterProvider.otherwise You can read more in the docs

Since I'm new user to Angular, this is just what i did to solve my problem, which was very similar to yours. Hope it can help you.

查看更多
Emotional °昔
3楼-- · 2020-04-16 03:00

I had the same issue, and I fixed it by adding this:

app.config(..., $urlMatcherFactoryProvider) {
    $urlMatcherFactoryProvider.strictMode(false);
});

This is because my route was adding a trailing slash / at the end of the paths and $stateProvider was not recognizing the URL, thus taking me back to the home state.

查看更多
登录 后发表回答