Перенаправлення на певний маршрут залежно від умови


493

Я пишу невеликий додаток AngularJS, який має вхід та основний вигляд, налаштований так:

$routeProvider
 .when('/main' , {templateUrl: 'partials/main.html',  controller: MainController})
 .when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
 .otherwise({redirectTo: '/login'});

Мій LoginController перевіряє комбінацію користувача / пароля та встановлює властивість на $ rootScope, що відображає це:

function LoginController($scope, $location, $rootScope) {
 $scope.attemptLogin = function() {
   if ( $scope.username == $scope.password ) { // test
        $rootScope.loggedUser = $scope.username;
        $location.path( "/main" );
    } else {
        $scope.loginError = "Invalid user/pass.";
    }
}

Все працює, але якщо я отримаю доступ, http://localhost/#/mainя закінчую обхід екрана входу. Я хотів написати щось на кшталт "кожного разу, коли маршрут змінюється, якщо $ rootScope.loggedUser є нульовим, то переадресація на / вхід"

...

... чекай. Чи можу я якось слухати зміни маршруту? Я все-таки опублікую це питання і продовжую шукати.


3
Просто для уточнення: хоча багато рішень нижче працюють добре, я останнім часом більше схильний прийняти відповідь @ Oran нижче - тобто, сервер відповість кодом 401, коли його запитують про конфіденційну URL-адресу, і використовувати цю інформацію для контролю "поле для входу" на клієнті. (Однак присяжне все ще виходить на "черги відхилених запитів та перездачу їх пізніше", принаймні для мене :))
st.never

Відповіді:


510

Після деякого дайвінгу через деяку документацію та вихідний код, я думаю, я працював. Можливо, це буде корисно для когось іншого?

Я додав у конфігурацію свого модуля наступне:

angular.module(...)
 .config( ['$routeProvider', function($routeProvider) {...}] )
 .run( function($rootScope, $location) {

    // register listener to watch route changes
    $rootScope.$on( "$routeChangeStart", function(event, next, current) {
      if ( $rootScope.loggedUser == null ) {
        // no logged user, we should be going to #login
        if ( next.templateUrl != "partials/login.html" ) {
          // not going to #login, we should redirect now
          $location.path( "/login" );
        }
      }         
    });
 })

Одним, що здається дивним, є те, що мені довелося перевірити часткове ім’я ( login.html), оскільки в "наступного" об'єкта Route не було URL-адреси чи чогось іншого. Може, є кращий спосіб?


13
Класна людина, дякую за те, що ви поділилися своїм рішенням. Варто зазначити одне: у поточній версії це "наступний. $ Route.templateUrl"
doubledriscoll

5
Якщо ви подивитесь на мережеві запити в хромовому інспекторі, маршрут, який переадресовується (оскільки користувач не ввійшов у систему), все одно викликається, і відповідь надсилається до браузера, і тоді викликується перенаправлений шлях '/ логін'. Тож цей спосіб не є корисним, оскільки користувачі, які не ввійшли в систему, можуть бачити відповідь на маршрут, до якого він не повинен мати доступ.
sonicboom

34
Використовуйте $ locationChangeStart замість $ routeChangeStart, щоб запобігти виклику маршруту та дозволити неавторизованим користувачам переглядати вміст, до якого вони не повинні мати доступ.
sonicboom

17
Пам'ятайте, що це клієнт. Також повинен бути серверний бар'єр.
Нейкос

2
@sonicboom $ locationChangeStart не має сенсу, якщо не для всіх маршрутів потрібна автентифікація, за допомогою $ routeChangeStart ви можете мати метадані про об’єкти маршруту, такі як автентифікація чи ні, або які ролі потрібні для цього маршруту. Ваш сервер повинен обробляти не показувати несанкціонований вміст, і AngularJS не почне обробляти, поки після зміни маршруту все одно не з’явиться, тому нічого не повинно бути показано.
Кріс Нікола

93

Ось, можливо, більш елегантне та гнучкіше рішення із властивістю конфігурації 'резолірування' та «обіцянками», що дозволяє можливе завантаження даних на правилах маршрутизації та маршрутизації залежно від даних.

Ви вказуєте функцію в "вирішити" в конфігурації маршрутизації, а також у функції завантаження та перевірки даних, виконайте всі перенаправлення. Якщо вам потрібно завантажити дані, ви повернете обіцянку, якщо вам потрібно зробити переадресацію - відхиліть обіцянку перед цим. Усі деталі можна знайти на сторінках $ routerProvider та $ q документації.

'use strict';

var app = angular.module('app', [])
    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/', {
                templateUrl: "login.html",
                controller: LoginController
            })
            .when('/private', {
                templateUrl: "private.html",
                controller: PrivateController,
                resolve: {
                    factory: checkRouting
                }
            })
            .when('/private/anotherpage', {
                templateUrl:"another-private.html",
                controller: AnotherPriveController,
                resolve: {
                    factory: checkRouting
                }
            })
            .otherwise({ redirectTo: '/' });
    }]);

var checkRouting= function ($q, $rootScope, $location) {
    if ($rootScope.userProfile) {
        return true;
    } else {
        var deferred = $q.defer();
        $http.post("/loadUserProfile", { userToken: "blah" })
            .success(function (response) {
                $rootScope.userProfile = response.userProfile;
                deferred.resolve(true);
            })
            .error(function () {
                deferred.reject();
                $location.path("/");
             });
        return deferred.promise;
    }
};

Для російськомовних людей є допис на хабрі " Вариант условного раутинга в AngularJS ."


1
чому функція checkRouting відображається на заводі? Чи має значення те, на що це відображено?
honkskillet

@honkskillet: З кутового $ routeProvider docs: "factory - {string | function}: Якщо рядок, то це псевдонім для служби. В іншому випадку, якщо функція, то вона вводиться і значення, що повертається, трактується як залежність. Якщо Результат - це обіцянка, він вирішується до введення його значення в контролер. Будьте в курсі, що ngRoute. $ routeParams все ще буде посилатися на попередній маршрут у межах цих функцій вирішення. Використовуйте $ route.current.params для доступу до нових параметрів маршруту, замість цього ". Також з документів на вирішення: "Якщо будь-яку з обіцянок відхилено, подія $ routeChangeError запускається."
Тім Перрі

Якщо ui.routerвикористовується, використовуйте $stateProvider замість $routeProvider.
TRiNE

61

Я намагався зробити те саме. Придумали ще одне простіше рішення після роботи з колегою. У мене встановлений годинник $location.path(). Це робить трюк. Я тільки починаю вивчати AngularJS і вважаю, що це буде більш чистим і читабельним.

$scope.$watch(function() { return $location.path(); }, function(newValue, oldValue){  
    if ($scope.loggedIn == false && newValue != '/login'){  
            $location.path('/login');  
    }  
});

Це виглядає дуже цікаво. Чи змогли ви десь розмістити приклад?
kyleroche

3
Де ви встановлюєте годинник?
freakTheMighty

3
@freakTheMighty Ви повинні налаштувати годинник у своїй функції mainCtrl, де ng-контролер встановлений на mainCtrl. наприклад, <body ng-controller = "mainCtrl">
user1807337

5
Я думаю, що справедливо лише те, що якщо є негативний голос, він повинен мати коментар з обґрунтуванням. Це допоможе як інструмент навчання.
user1807337

37

Інший спосіб здійснення перенаправлення входу - це використання подій та перехоплювачів, як описано тут . У статті описано деякі додаткові переваги, такі як виявлення необхідності входу в систему, встановлення черги на запити та відтворення їх після успішного входу.

Ви можете спробувати робочу демонстраційну версію тут і переглянути демо-джерело тут .


3
Чи можете ви оновити цю відповідь, щоб включити відповідну інформацію за посиланнями? Таким чином, він і надалі стане корисним для відвідувачів, навіть якщо посилання знизяться.
josliber

34

1. Встановити поточного глобального користувача.

У сервісі аутентифікації встановіть поточного користувача, що аутентифікується, на кореневій області.

// AuthService.js

  // auth successful
  $rootScope.user = user

2. Встановіть функцію auth на кожному захищеному маршруті.

// AdminController.js

.config(function ($routeProvider) {
  $routeProvider.when('/admin', {
    controller: 'AdminController',
    auth: function (user) {
      return user && user.isAdmin
    }
  })
})

3. Перевірте авт на кожну зміну маршруту.

// index.js

.run(function ($rootScope, $location) {
  $rootScope.$on('$routeChangeStart', function (ev, next, curr) {
    if (next.$$route) {
      var user = $rootScope.user
      var auth = next.$$route.auth
      if (auth && !auth(user)) { $location.path('/') }
    }
  })
})

Крім того, ви можете встановити дозволи на об’єкт користувача та призначити кожному маршруту дозвіл, а потім перевірити дозвіл у зворотному дзвінку події.


@malcolmhall так, це налаштування, і ви хочете відмовитися. Натомість додайте "загальнодоступний" булевий доступ до загальнодоступних маршрутів, таких як сторінка входу, і перенаправляйтеif (!user && !next.$$route.public)
AJcodez

Може хтось, будь ласка, пояснить next.$$routeмені? Я не знаходжу нічого в кутових документах, які описують аргументи, що даються $routeChangeStartподії, але я припускаю, nextчи currце якісь об'єкти розташування? $$routeТрохи важко Google.
skagedal

2
Тепер я бачу, що $$routeвластивість є приватною змінною Angular's. Ви не повинні покладатися на це, див. Наприклад: stackoverflow.com/a/19338518/1132101 - якщо це зробити, ваш код може зламатися при зміні кута.
skagedal

2
Я знайшов спосіб отримати доступ до маршруту без доступу до приватної власності або з Переберія $route.routesдля створення списку (як в @ thataustin Відповімо): отримати шлях до папки з next.originalPathі використовувати, щоб індекс $route.routes: var auth = $route.routes[next.originalPath].
skagedal

Щодо відповіді на моє запитання з трьох коментарів тому щодо аргументів, які висуваються до події - вони, здається, справді не є документальними, дивіться це питання, яке також трапляється для посилання на це питання ТА
скагедал

27

Ось як я це зробив, якщо він комусь допомагає:

У налаштуваннях я встановлюю publicAccessатрибут для кількох маршрутів, які я хочу відкрити для загального користування (наприклад, увійти або зареєструватися):

$routeProvider
    .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeCtrl'
    })
    .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl',
        publicAccess: true
    })

то в блоці запуску я встановлюю слухача на $routeChangeStartподію, на яку переспрямовується, '/login'якщо користувач не має доступу або маршрут є загальнодоступним:

angular.module('myModule').run(function($rootScope, $location, user, $route) {

    var routesOpenToPublic = [];
    angular.forEach($route.routes, function(route, path) {
        // push route onto routesOpenToPublic if it has a truthy publicAccess value
        route.publicAccess && (routesOpenToPublic.push(path));
    });

    $rootScope.$on('$routeChangeStart', function(event, nextLoc, currentLoc) {
        var closedToPublic = (-1 === routesOpenToPublic.indexOf($location.path()));
        if(closedToPublic && !user.isLoggedIn()) {
            $location.path('/login');
        }
    });
})

Ви, очевидно, можете змінити умову isLoggedInна щось інше ... просто показавши інший спосіб це зробити.


а хто користувач у ваших аргументах блоку запуску? послуга?
mohamnag

так, це сервіс, який піклується про перевірку файлів cookie тощо, щоб побачити, чи користувач увійшов.
thataustin

Ви можете отримати доступ до маршруту, як nextLoc.$$route.publicAccessbtw.
AJcodez

Або використовувати $route.routes[nextLoc.originalPath], що не використовує приватну змінну.
skagedal

1
Насправді, ви можете просто перевірити nextLoc && nextLoc.publicAccess!
skagedal

9

Я роблю це за допомогою перехоплювачів. Я створив файл бібліотеки, який можна додати до файлу index.html. Таким чином ви матимете глобальну обробку помилок для своїх дзвінків служби відпочинку та не потрібно дбати про всі помилки окремо. Далі вниз я також вставив свою основну бібліотеку для входу в систему-авторист. Там ви бачите, що я також перевіряю наявність помилки 401 та переадресацію на інше місце. Див. Lib / ea-basic-auth-login.js

lib / http-error-handling.js

/**
* @ngdoc overview
* @name http-error-handling
* @description
*
* Module that provides http error handling for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/http-error-handling.js"></script>
* Add <div class="messagesList" app-messages></div> to the index.html at the position you want to
* display the error messages.
*/
(function() {
'use strict';
angular.module('http-error-handling', [])
    .config(function($provide, $httpProvider, $compileProvider) {
        var elementsList = $();

        var showMessage = function(content, cl, time) {
            $('<div/>')
                .addClass(cl)
                .hide()
                .fadeIn('fast')
                .delay(time)
                .fadeOut('fast', function() { $(this).remove(); })
                .appendTo(elementsList)
                .text(content);
        };

        $httpProvider.responseInterceptors.push(function($timeout, $q) {
            return function(promise) {
                return promise.then(function(successResponse) {
                    if (successResponse.config.method.toUpperCase() != 'GET')
                        showMessage('Success', 'http-success-message', 5000);
                    return successResponse;

                }, function(errorResponse) {
                    switch (errorResponse.status) {
                        case 400:
                            showMessage(errorResponse.data.message, 'http-error-message', 6000);
                                }
                            }
                            break;
                        case 401:
                            showMessage('Wrong email or password', 'http-error-message', 6000);
                            break;
                        case 403:
                            showMessage('You don\'t have the right to do this', 'http-error-message', 6000);
                            break;
                        case 500:
                            showMessage('Server internal error: ' + errorResponse.data.message, 'http-error-message', 6000);
                            break;
                        default:
                            showMessage('Error ' + errorResponse.status + ': ' + errorResponse.data.message, 'http-error-message', 6000);
                    }
                    return $q.reject(errorResponse);
                });
            };
        });

        $compileProvider.directive('httpErrorMessages', function() {
            return {
                link: function(scope, element, attrs) {
                    elementsList.push($(element));
                }
            };
        });
    });
})();

css / http-error-handling.css

.http-error-message {
    background-color: #fbbcb1;
    border: 1px #e92d0c solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

.http-error-validation-message {
    background-color: #fbbcb1;
    border: 1px #e92d0c solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

http-success-message {
    background-color: #adfa9e;
    border: 1px #25ae09 solid;
    font-size: 12px;
    font-family: arial;
    padding: 10px;
    width: 702px;
    margin-bottom: 1px;
}

index.html

<!doctype html>
<html lang="en" ng-app="cc">
    <head>
        <meta charset="utf-8">
        <title>yourapp</title>
        <link rel="stylesheet" href="css/http-error-handling.css"/>
    </head>
    <body>

<!-- Display top tab menu -->
<ul class="menu">
  <li><a href="#/user">Users</a></li>
  <li><a href="#/vendor">Vendors</a></li>
  <li><logout-link/></li>
</ul>

<!-- Display errors -->
<div class="http-error-messages" http-error-messages></div>

<!-- Display partial pages -->
<div ng-view></div>

<!-- Include all the js files. In production use min.js should be used -->
<script src="lib/angular114/angular.js"></script>
<script src="lib/angular114/angular-resource.js"></script>
<script src="lib/http-error-handling.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>

lib / ea-basic-auth-login.js

Майже те ж саме можна зробити для входу. Тут ви маєте відповідь на переадресацію ($ location.path ("/ вхід")).

/**
* @ngdoc overview
* @name ea-basic-auth-login
* @description
*
* Module that provides http basic authentication for apps.
*
* Usage:
* Hook the file in to your index.html: <script src="lib/ea-basic-auth-login.js">  </script>
* Place <ea-login-form/> tag in to your html login page
* Place <ea-logout-link/> tag in to your html page where the user has to click to logout
*/
(function() {
'use strict';
angular.module('ea-basic-auth-login', ['ea-base64-login'])
    .config(['$httpProvider', function ($httpProvider) {
        var ea_basic_auth_login_interceptor = ['$location', '$q', function($location, $q) {
            function success(response) {
                return response;
            }

            function error(response) {
                if(response.status === 401) {
                    $location.path('/login');
                    return $q.reject(response);
                }
                else {
                    return $q.reject(response);
                }
            }

            return function(promise) {
                return promise.then(success, error);
            }
        }];
        $httpProvider.responseInterceptors.push(ea_basic_auth_login_interceptor);
    }])
    .controller('EALoginCtrl', ['$scope','$http','$location','EABase64Login', function($scope, $http, $location, EABase64Login) {
        $scope.login = function() {
            $http.defaults.headers.common['Authorization'] = 'Basic ' + EABase64Login.encode($scope.email + ':' + $scope.password);
            $location.path("/user");
        };

        $scope.logout = function() {
            $http.defaults.headers.common['Authorization'] = undefined;
            $location.path("/login");
        };
    }])
    .directive('eaLoginForm', [function() {
        return {
            restrict:   'E',
            template:   '<div id="ea_login_container" ng-controller="EALoginCtrl">' +
                        '<form id="ea_login_form" name="ea_login_form" novalidate>' +
                        '<input id="ea_login_email_field" class="ea_login_field" type="text" name="email" ng-model="email" placeholder="E-Mail"/>' +
                        '<br/>' +
                        '<input id="ea_login_password_field" class="ea_login_field" type="password" name="password" ng-model="password" placeholder="Password"/>' +
                        '<br/>' +
                        '<button class="ea_login_button" ng-click="login()">Login</button>' +
                        '</form>' +
                        '</div>',
            replace: true
        };
    }])
    .directive('eaLogoutLink', [function() {
        return {
            restrict: 'E',
            template: '<a id="ea-logout-link" ng-controller="EALoginCtrl" ng-click="logout()">Logout</a>',
            replace: true
        }
    }]);

angular.module('ea-base64-login', []).
    factory('EABase64Login', function() {
        var keyStr = 'ABCDEFGHIJKLMNOP' +
            'QRSTUVWXYZabcdef' +
            'ghijklmnopqrstuv' +
            'wxyz0123456789+/' +
            '=';

        return {
            encode: function (input) {
                var output = "";
                var chr1, chr2, chr3 = "";
                var enc1, enc2, enc3, enc4 = "";
                var i = 0;

                do {
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);

                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;

                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    }

                    output = output +
                        keyStr.charAt(enc1) +
                        keyStr.charAt(enc2) +
                        keyStr.charAt(enc3) +
                        keyStr.charAt(enc4);
                    chr1 = chr2 = chr3 = "";
                    enc1 = enc2 = enc3 = enc4 = "";
                } while (i < input.length);

                return output;
            },

            decode: function (input) {
                var output = "";
                var chr1, chr2, chr3 = "";
                var enc1, enc2, enc3, enc4 = "";
                var i = 0;

                // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
                var base64test = /[^A-Za-z0-9\+\/\=]/g;
                if (base64test.exec(input)) {
                    alert("There were invalid base64 characters in the input text.\n" +
                        "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
                        "Expect errors in decoding.");
                }
                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

                do {
                    enc1 = keyStr.indexOf(input.charAt(i++));
                    enc2 = keyStr.indexOf(input.charAt(i++));
                    enc3 = keyStr.indexOf(input.charAt(i++));
                    enc4 = keyStr.indexOf(input.charAt(i++));

                    chr1 = (enc1 << 2) | (enc2 >> 4);
                    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                    chr3 = ((enc3 & 3) << 6) | enc4;

                    output = output + String.fromCharCode(chr1);

                    if (enc3 != 64) {
                        output = output + String.fromCharCode(chr2);
                    }
                    if (enc4 != 64) {
                        output = output + String.fromCharCode(chr3);
                    }

                    chr1 = chr2 = chr3 = "";
                    enc1 = enc2 = enc3 = enc4 = "";

                } while (i < input.length);

                return output;
            }
        };
    });
})();

2
Ви дійсно повинні триматися осторонь від того, щоб робити маніпуляції з домом у JS, якщо не передбачено директивою. Якщо ви просто налаштували свою логіку і використовуєте ng-class для застосування класу та запускаєте анімацію CSS, ви подякуєте пізніше.
Запитувачі

7

У вашому файлі app.js:

.run(["$rootScope", "$state", function($rootScope, $state) {

      $rootScope.$on('$locationChangeStart', function(event, next, current) {
        if (!$rootScope.loggedUser == null) {
          $state.go('home');
        }    
      });
}])

4

Можна перенаправити на інший вигляд за допомогою кутового маршрутизатора . Для цього у нас є метод $state.go("target_view"). Наприклад:

 ---- app.js -----

 var app = angular.module('myApp', ['ui.router']);

 app.config(function ($stateProvider, $urlRouterProvider) {

    // Otherwise
    $urlRouterProvider.otherwise("/");

    $stateProvider
            // Index will decide if redirects to Login or Dashboard view
            .state("index", {
                 url: ""
                 controller: 'index_controller'
              })
            .state('dashboard', {
                url: "/dashboard",
                controller: 'dashboard_controller',
                templateUrl: "views/dashboard.html"
              })
            .state('login', {
                url: "/login",
                controller: 'login_controller',
                templateUrl: "views/login.html"
              });
 });

 // Associate the $state variable with $rootScope in order to use it with any controller
 app.run(function ($rootScope, $state, $stateParams) {
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
    });

 app.controller('index_controller', function ($scope, $log) {

    /* Check if the user is logged prior to use the next code */

    if (!isLoggedUser) {
        $log.log("user not logged, redirecting to Login view");
        // Redirect to Login view 
        $scope.$state.go("login");
    } else {
        // Redirect to dashboard view 
        $scope.$state.go("dashboard");
    }

 });

----- HTML -----

<!DOCTYPE html>
<html>
    <head>
        <title>My WebSite</title>

        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="description" content="MyContent">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <script src="js/libs/angular.min.js" type="text/javascript"></script>
        <script src="js/libs/angular-ui-router.min.js" type="text/javascript"></script>
        <script src="js/app.js" type="text/javascript"></script>

    </head>
    <body ng-app="myApp">
        <div ui-view></div>
    </body>
</html>

3

Якщо ви не хочете використовувати angular-ui-роутер, але хочете, щоб ваші контролери ліниво завантажувались через RequireJS, є кілька проблем із подіями $routeChangeStartпри використанні ваших контролерів як модулів RequireJS (ледачий завантажений).

Ви не можете бути впевнені, що контролер буде завантажений до $routeChangeStartйого запуску - адже він не буде завантажений. Це означає, що ви не можете отримати доступ до властивостей nextмаршруту, таких як localsабо $$routeтому, що вони ще не налаштовані.
Приклад:

app.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/foo", {
        controller: "Foo",
        resolve: {
            controller: ["$q", function($q) {
                var deferred = $q.defer();
                require(["path/to/controller/Foo"], function(Foo) {
                    // now controller is loaded
                    deferred.resolve();
                });
                return deferred.promise;
            }]
        }
    });
}]);

app.run(["$rootScope", function($rootScope) {
    $rootScope.$on("$routeChangeStart", function(event, next, current) {
        console.log(next.$$route, next.locals); // undefined, undefined
    });
}]);

Це означає, що ви не можете перевірити права доступу там.

Рішення:

Оскільки завантаження контролера здійснюється через дозвіл, ви можете зробити те ж саме, перевіривши контроль доступу:

app.config(["$routeProvider", function($routeProvider) {
    $routeProvider.when("/foo", {
        controller: "Foo",
        resolve: {
            controller: ["$q", function($q) {
                var deferred = $q.defer();
                require(["path/to/controller/Foo"], function(Foo) {
                    // now controller is loaded
                    deferred.resolve();
                });
                return deferred.promise;
            }],
            access: ["$q", function($q) {
                var deferred = $q.defer();
                if (/* some logic to determine access is granted */) {
                    deferred.resolve();
                } else {
                    deferred.reject("You have no access rights to go there");
                }
                return deferred.promise;
            }],
        }
    });
}]);

app.run(["$rootScope", function($rootScope) {
    $rootScope.$on("$routeChangeError", function(event, next, current, error) {
        console.log("Error: " + error); // "Error: You have no access rights to go there"
    });
}]);

Зверніть увагу, що замість того, щоб використовувати подію, $routeChangeStartяку я використовую$routeChangeError


-4
    $routeProvider
 .when('/main' , {templateUrl: 'partials/main.html',  controller: MainController})
 .when('/login', {templateUrl: 'partials/login.html', controller: LoginController}).
 .when('/login', {templateUrl: 'partials/index.html', controller: IndexController})
 .otherwise({redirectTo: '/index'});

Це основна конфігурація маршруту ... Де ми перевіряємо будь-яку умову перед перенаправленням на налаштовані маршрути ..?
TJ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.