Chuyển hướng đến một tuyến đường nhất định dựa trên điều kiện


493

Tôi đang viết một ứng dụng AngularJS nhỏ có chế độ xem đăng nhập và chế độ xem chính, được định cấu hình như sau:

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

Đăng nhập Trình kiểm soát của tôi kiểm tra kết hợp người dùng / vượt qua và đặt thuộc tính trên $ rootScope phản ánh điều này:

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.";
    }
}

Mọi thứ đều hoạt động, nhưng nếu tôi truy cập http://localhost/#/main cuối cùng tôi sẽ bỏ qua màn hình đăng nhập. Tôi muốn viết một cái gì đó như "bất cứ khi nào tuyến đường thay đổi, nếu $ rootScope.loggedUser là null thì hãy chuyển hướng đến / đăng nhập"

...

... chờ đợi. Tôi có thể lắng nghe thay đổi tuyến đường bằng cách nào đó? Tôi sẽ đăng câu hỏi này và tiếp tục tìm kiếm.


3
Chỉ cần làm rõ: trong khi nhiều giải pháp bên dưới hoạt động tốt, gần đây tôi đã có xu hướng chấp nhận câu trả lời của @ Oran bên dưới - nghĩa là máy chủ trả lời bằng mã 401 khi được yêu cầu URL nhạy cảm và sử dụng thông tin đó để kiểm soát "hộp đăng nhập" trên máy khách. (Tuy nhiên, bồi thẩm đoàn vẫn không đưa ra "bit yêu cầu từ chối xếp hàng và cấp lại chúng sau", ít nhất là đối với tôi :))
st.never

Câu trả lời:


510

Sau khi lặn qua một số tài liệu và mã nguồn, tôi nghĩ rằng tôi đã làm cho nó hoạt động. Có lẽ điều này sẽ hữu ích cho người khác?

Tôi đã thêm vào cấu hình mô-đun sau đây:

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" );
        }
      }         
    });
 })

Một điều có vẻ kỳ lạ là tôi đã phải kiểm tra tên một phần ( login.html) vì đối tượng Tuyến "tiếp theo" không có url hoặc thứ gì khác. Có lẽ có một cách tốt hơn?


13
Người đàn ông tuyệt vời, cảm ơn vì đã chia sẻ giải pháp của bạn. Một điều cần lưu ý: trong phiên bản hiện tại, đó là "next. $ Route.templateUrl"
doubledriscoll

5
Nếu bạn xem các yêu cầu mạng trong trình kiểm tra chrome, tuyến đường đang được chuyển hướng (vì người dùng chưa đăng nhập) vẫn được gọi và phản hồi sẽ được gửi tới trình duyệt và sau đó đường dẫn được chuyển hướng '/ đăng nhập' được gọi. Vì vậy, phương pháp này không tốt vì người dùng không đăng nhập có thể thấy phản hồi cho tuyến đường mà họ không nên truy cập.
sonicboom

34
Sử dụng $ locationChangeStart thay vì $ routeChangeStart để ngăn tuyến đường được gọi và cho phép người dùng không được xác thực xem nội dung mà họ không nên truy cập.
sonicboom

17
Hãy nhớ rằng đây là khách hàng. Cũng cần có một rào cản máy chủ.
Neikos

2
@sonicboom $ locationChangeStart không có nghĩa gì nếu không phải tất cả các tuyến đều yêu cầu xác thực, với $ routeChangeStart, bạn có thể có siêu dữ liệu trên các đối tượng tuyến, chẳng hạn như nó có được xác thực hay không hoặc vai trò nào được yêu cầu cho tuyến đó. Máy chủ của bạn sẽ xử lý không hiển thị nội dung không được xác thực và AngularJS sẽ không bắt đầu xử lý cho đến khi tuyến đường thay đổi, vì vậy không có gì được hiển thị.
Chris Nicola

93

Đây có thể là một giải pháp thanh lịch và linh hoạt hơn với thuộc tính cấu hình 'giải quyết' và 'lời hứa' cho phép tải dữ liệu cuối cùng theo quy tắc định tuyến và định tuyến tùy thuộc vào dữ liệu.

Bạn chỉ định một chức năng trong 'giải quyết' trong cấu hình định tuyến và trong chức năng tải và kiểm tra dữ liệu, thực hiện tất cả các chuyển hướng. Nếu bạn cần tải dữ liệu, bạn trả lại một lời hứa, nếu bạn cần thực hiện chuyển hướng - từ chối lời hứa trước đó. Tất cả các chi tiết có thể được tìm thấy trên các trang tài liệu $ 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;
    }
};

Đối với những người nói tiếng Nga, có một bài đăng trên habr " Вариит условного раутинга в AngularJS ."


1
Tại sao chức năng checkRouting được ánh xạ tới nhà máy? Có vấn đề gì với bản đồ không?
honkskillet

@honkskillet: Từ các tài liệu $ routeProvider góc cạnh: "Factory - {string | function}: Nếu chuỗi thì đó là bí danh cho một dịch vụ. Nếu không, nếu chức năng, thì nó được thêm vào và giá trị trả về được coi là phụ thuộc. Nếu Kết quả là một lời hứa, nó được giải quyết trước khi giá trị của nó được đưa vào bộ điều khiển. Xin lưu ý rằng ngRoute. $ routeParams vẫn sẽ tham chiếu tuyến trước trong các hàm phân giải này. Sử dụng $ route.cản.params để truy cập các tham số tuyến mới, thay thế." Cũng từ các tài liệu về giải quyết: "Nếu bất kỳ lời hứa nào bị từ chối, sự kiện $ routeChangeError sẽ bị hủy."
Tim Perry

Nếu ui.routerđược sử dụng, sử dụng $stateProvider thay vì $routeProvider.
TRiNE

61

Tôi đã cố gắng làm như vậy. Đến với một giải pháp đơn giản hơn sau khi làm việc với một đồng nghiệp. Tôi có một chiếc đồng hồ được thiết lập trên $location.path(). Đó là mẹo. Tôi mới bắt đầu tìm hiểu AngularJS và thấy điều này sẽ rõ ràng và dễ đọc hơn.

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

Điều này có vẻ rất thú vị. Bạn có thể gửi một ví dụ ở đâu đó không?
kyleroche

3
Nơi nào bạn thiết lập đồng hồ?
freakTheMighty

3
@freakTheMighty Bạn phải thiết lập đồng hồ trong chức năng mainCtrl của mình, trong đó bộ điều khiển ng được đặt thành mainCtrl. ví dụ <body ng-controller = "mainCtrl">
user1807337

5
Tôi nghĩ thật công bằng khi có một cuộc bỏ phiếu tiêu cực được đưa ra, nó nên có một bình luận với lý do. Nó sẽ giúp như một công cụ học tập.
dùng1807337

37

Một cách khác để thực hiện chuyển hướng đăng nhập là sử dụng các sự kiện và đánh chặn như được mô tả ở đây . Bài viết mô tả một số lợi thế bổ sung như phát hiện khi cần đăng nhập, xếp hàng các yêu cầu và phát lại chúng sau khi đăng nhập thành công.

Bạn có thể thử bản demo hoạt động tại đây và xem nguồn demo tại đây .


3
Bạn có thể vui lòng cập nhật câu trả lời này để bao gồm các thông tin liên quan từ các liên kết? Bằng cách đó, nó sẽ tiếp tục hữu ích cho khách truy cập ngay cả khi các liên kết đi xuống.
josliber

34

1. Đặt người dùng hiện tại toàn cầu.

Trong dịch vụ xác thực của bạn, đặt người dùng hiện được xác thực trên phạm vi gốc.

// AuthService.js

  // auth successful
  $rootScope.user = user

2. Đặt chức năng xác thực trên mỗi tuyến được bảo vệ.

// AdminController.js

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

3. Kiểm tra auth trên mỗi thay đổi tuyến đường.

// 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('/') }
    }
  })
})

Ngoài ra, bạn có thể đặt quyền trên đối tượng người dùng và gán cho mỗi tuyến một quyền, sau đó kiểm tra quyền trong cuộc gọi lại sự kiện.


@malcolmhall yup, đây là chọn tham gia và bạn muốn từ chối. Thay vào đó, hãy thêm một boolean "công khai" vào các tuyến công cộng như trang đăng nhập và chuyển hướngif (!user && !next.$$route.public)
AJcodez 11/03/2015

Ai đó có thể vui lòng giải thích next.$$routecho tôi? Tôi không tìm thấy gì trong các tài liệu Angular mô tả các đối số đưa ra cho một $routeChangeStartsự kiện, nhưng tôi giả sử nextcurrlà một số loại đối tượng vị trí? Một $$routechút là khó để google.
skagedal

2
Bây giờ tôi thấy rằng $$routetài sản là một biến riêng của Angular's. Bạn không nên dựa vào điều đó, xem ví dụ: stackoverflow.com/a/19338518/1132101 - nếu bạn làm vậy, mã của bạn có thể bị hỏng khi Angular thay đổi.
skagedal

2
Tôi đã tìm thấy cách truy cập tuyến đường mà không cần truy cập vào một tài sản riêng hoặc phải lặp $route.routeslại để xây dựng một danh sách (như trong câu trả lời của @ thataustin): lấy đường dẫn cho vị trí next.originalPathvà sử dụng chỉ mục đó để lập chỉ mục $route.routes: var auth = $route.routes[next.originalPath].
skagedal

Để trả lời câu hỏi của tôi từ ba bình luận trước đây về các đối số được đưa ra cho sự kiện - chúng dường như thực sự không có giấy tờ, hãy xem vấn đề này cũng xảy ra để tham khảo câu hỏi SO này: github.com/angular/angular.js/issues/ 10.994
skagedal

27

Đây là cách tôi đã làm, trong trường hợp nó giúp được bất cứ ai:

Trong cấu hình, tôi đặt một publicAccessthuộc tính trên một vài tuyến mà tôi muốn mở cho công chúng (như đăng nhập hoặc đăng ký):

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

sau đó trong một khối chạy, tôi đặt một trình lắng nghe về $routeChangeStartsự kiện chuyển hướng đến '/login'trừ khi người dùng có quyền truy cập hoặc tuyến đường có thể truy cập công khai:

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');
        }
    });
})

Bạn rõ ràng có thể thay đổi điều kiện từ isLoggedInbất kỳ điều gì khác ... chỉ cần hiển thị một cách khác để làm điều đó.


và người dùng trong các đối số khối chạy của bạn là gì? một dịch vụ?
mohamnag

vâng, đó là một dịch vụ chăm sóc kiểm tra cookie, v.v. để xem người dùng đã đăng nhập chưa
thataustin

Bạn có thể truy cập các tuyến đường như nextLoc.$$route.publicAccessbtw.
AJcodez

Hoặc sử dụng $route.routes[nextLoc.originalPath], không sử dụng một biến riêng tư.
skagedal

1
Trên thực tế, bạn chỉ có thể kiểm tra nextLoc && nextLoc.publicAccess!
skagedal

9

Tôi đang làm điều đó bằng cách sử dụng các thiết bị đánh chặn. Tôi đã tạo một tệp thư viện có thể được thêm vào tệp index.html. Bằng cách này, bạn sẽ xử lý lỗi toàn cầu cho các cuộc gọi dịch vụ nghỉ ngơi của mình và không phải quan tâm đến tất cả các lỗi riêng lẻ. Xa hơn nữa tôi cũng dán thư viện đăng nhập cơ bản của mình. Ở đó bạn có thể thấy rằng tôi cũng kiểm tra lỗi 401 và chuyển hướng đến một vị trí khác. Xem lib / ea-basic-auth-login.js

lib / http-error-Xử lý.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-Xử lý.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

Gần như có thể được thực hiện để đăng nhập. Tại đây bạn có câu trả lời cho chuyển hướng ($ location.path ("/ login")).

/**
* @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
Bạn thực sự nên tránh xa việc thực hiện thao tác dom trong JS trừ khi bạn có chỉ thị. Nếu bạn chỉ thiết lập logic của mình và sau đó sử dụng ng-class để áp dụng một lớp và kích hoạt hoạt hình CSS, bạn sẽ cảm ơn chính mình sau này.
Người hỏi

7

Trong tệp app.js của bạn:

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

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

4

Có thể chuyển hướng đến một chế độ xem khác với bộ định tuyến góc . Đối với mục đích này, chúng tôi có phương pháp $state.go("target_view"). Ví dụ:

 ---- 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

Nếu bạn không muốn sử dụng bộ định tuyến góc, nhưng muốn bộ điều khiển của bạn được tải lười biếng qua RequireJS, có một số vấn đề với sự kiện $routeChangeStartkhi sử dụng bộ điều khiển của bạn dưới dạng mô-đun RequireJS (tải lười biếng).

Bạn không thể chắc chắn bộ điều khiển sẽ được tải trước khi $routeChangeStartđược kích hoạt - thực tế nó sẽ không được tải. Điều đó có nghĩa là bạn không thể truy cập các thuộc tính của nexttuyến như localshoặc $$routevì chúng chưa được thiết lập.
Thí dụ:

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
    });
}]);

Điều này có nghĩa là bạn không thể kiểm tra quyền truy cập trong đó.

Giải pháp:

Vì việc tải bộ điều khiển được thực hiện thông qua giải quyết, bạn có thể thực hiện tương tự với kiểm tra kiểm soát truy cập của mình:

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"
    });
}]);

Lưu ý ở đây là thay vì sử dụng sự kiện $routeChangeStarttôi đang sử dụng$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'});

Đây là cấu hình tuyến cơ bản ... Chúng ta đang kiểm tra bất kỳ điều kiện nào trước khi chuyển hướng đến các tuyến được định cấu hình ..?
TJ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.