Duruma göre belirli bir rotaya yönlendirme


493

Bir giriş görünümü ve ana görünümü olan küçük bir AngularJS uygulaması yazıyorum, şöyle yapılandırılmış:

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

LoginController kullanıcı / pass kombinasyonunu kontrol eder ve $ rootScope üzerinde bunu yansıtan bir özellik ayarlar:

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

Her şey çalışıyor, ancak erişirsem http://localhost/#/maingiriş ekranını atlarım. "Güzergah değiştiğinde, $ rootScope.okedUser boşsa / sonra giriş için yönlendir" gibi bir şey yazmak istedim

...

... Bekle. Rota değişikliklerini bir şekilde dinleyebilir miyim? Bu soruyu yine de göndereceğim ve aramaya devam edeceğim.


3
Açıklığa kavuşturmak için: aşağıdaki birçok çözüm iyi çalışıyor olsa da, kısa bir süre önce @ Oran'ın cevabını kabul etme eğilimindeyim - yani, hassas bir URL istendiğinde sunucunun 401 koduyla yanıt vermesini ve bu bilgileri kontrol etmek için kullanmasını sağladım istemcideki "giriş kutusu". (Bununla birlikte jüri üzerinde hala biraz, en azından :) benim için "reddedildi istek ve yeniden düzenleyen sonra bunları kuyruk")
st.never

Yanıtlar:


510

Bazı dokümantasyon ve kaynak kodları ile dalıştan sonra, çalıştığını düşünüyorum. Belki bu başka biri için yararlı olacaktır?

Modül yapılandırmamda aşağıdakileri ekledim:

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

Garip görünen bir şey login.html, "next" Route nesnesinde bir url veya başka bir şey olmadığı için kısmi adı ( ) test etmek zorunda olduğum . Belki daha iyi bir yol var?


13
Havalı adam, çözümünü paylaştığın için teşekkürler. Unutulmaması gereken bir şey: mevcut sürümde, "sonraki. $ Route.templateUrl"
doubledriscoll

5
Chrome denetçisindeki ağ isteklerine bakarsanız, yönlendirilen rota (kullanıcı oturum açmamış olduğu için) yine de çağrılır ve tarayıcıya bir yanıt gönderilir ve ardından yeniden yönlendirilen '/ login' yolu çağrılır. Bu nedenle, oturum açmamış kullanıcılar erişmemesi gereken bir yolun yanıtını görebildiğinden bu yöntem iyi değildir.
sonicboom

34
Rotanın çağrılmasını önlemek ve kimliği doğrulanmamış kullanıcıların erişmemeleri gereken içeriği görüntülemelerine izin vermek için $ routeChangeStart yerine $ locationChangeStart kullanın.
sonicboom

17
Bunun müşteri olduğunu unutmayın. Ayrıca bir sunucu bariyeri de olmalıdır.
Neikos

2
@sonicboom $ locationChangeStart, tüm güzergahlar kimlik doğrulaması gerektirmiyorsa mantıklı değildir; $ routeChangeStart ile, rota nesnelerinde, kimliği doğrulanıp doğrulanmadığı veya bu rota için hangi rollerin gerekli olduğu gibi meta verilere sahip olabilirsiniz. Sunucunuz, kimliği doğrulanmamış içerik göstermemeyi işlemelidir ve AngularJS, yol yine de değiştirilinceye kadar işlemeye başlamaz, bu nedenle hiçbir şey gösterilmemelidir.
Chris Nicola

93

Burada, "çözümleme" yapılandırma özelliği ve verilere bağlı olarak yönlendirme ve yönlendirme kurallarına nihai veri yüklemeyi mümkün kılan "vaatler" ile daha şık ve esnek bir çözüm olabilir.

Yönlendirme yapılandırmasında 'çöz' seçeneğinde bir işlev belirtir ve veri yükleme ve denetleme işlevinde tüm yönlendirmeleri yapın. Verileri yüklemeniz gerekiyorsa, bir yönlendirme yaparsınız, yeniden yönlendirmeniz gerekiyorsa - bundan önce sözünü reddet. Tüm detaylar $ routerProvider ve $ q dokümantasyon sayfalarında bulunabilir.

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

Rusça konuşan kişiler için " Вариант условного раутинга в AngularJS " adlı bir gönderi vardır .


1
checkRouting işlevi neden fabrikaya eşlendi? Ne eşlendiğinin önemi var mı?
honkskillet

@honkskillet: Açısal $ routeProvider dokümanlarından: "factory - {string | function}: Dize ise bir hizmetin takma adıdır. Aksi takdirde işlev varsa, enjekte edilir ve dönüş değeri bağımlılık olarak kabul edilir. sonuç bir sözdür, değeri denetleyiciye enjekte edilmeden önce çözümlenir. ngRoute. $ routeParams öğesinin yine de bu çözüm işlevleri içindeki önceki yola başvurduğunu unutmayın. Yeni route parametrelerine erişmek için $ route.current.params komutunu kullanın, yerine." Ayrıca çözülen dokümanlardan: "Vaatlerden herhangi biri reddedilirse $ routeChangeError olayı tetiklenir."
Tim Perry

Eğer ui.routerkullanılırsa, kullanmak $stateProvider yerine $routeProvider.
TRiNE

61

Ben de aynısını yapmaya çalışıyorum. Bir meslektaşınızla çalıştıktan sonra daha basit bir çözüm bulduk. Ayarlanmış bir saatim var $location.path(). Hile yapar. AngularJS öğrenmeye başladım ve bunu daha temiz ve okunabilir buluyorum.

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

Bu çok ilginç görünüyor. Bir yere örnek gönderebildiniz mi?
kyleroche

3
Saati nerede ayarlıyorsunuz?
freakTheMighty

3
@freakTheMighty Saati ng-denetleyicinin mainCtrl olarak ayarlandığı mainCtrl işlevinizde ayarlamanız gerekir. örn. <body ng-controller = "mainCtrl">
user1807337 16:13

5
Sanırım olumsuz bir oy verilirse, gerekçeli bir yorumu olması adil olur. Bir öğrenme aracı olarak yardımcı olacaktır.
user1807337

37

Giriş yönlendirmesini uygulamanın farklı bir yolu, burada açıklandığı gibi olayları ve önleyicileri kullanmaktır . Makale, bir oturum açma işleminin ne zaman gerekli olduğunu algılama, istekleri kuyruğa alma ve oturum açma başarılı olduktan sonra bunları yeniden oynatma gibi bazı ek avantajları açıklar.

Burada çalışan bir demo deneyebilir ve demo kaynağını buradan görüntüleyebilirsiniz .


3
Lütfen bağlantılardan ilgili bilgileri içerecek şekilde bu yanıtı güncelleyebilir misiniz? Bu şekilde, bağlantılar kopsa bile ziyaretçiler için faydalı olmaya devam edecektir.
josliber

34

1. Global geçerli kullanıcıyı ayarlayın.

Kimlik doğrulama hizmetinizde, şu anda kimliği doğrulanmış kullanıcıyı kök kapsamına ayarlayın.

// AuthService.js

  // auth successful
  $rootScope.user = user

2. Korunan her rotada auth işlevini ayarlayın.

// AdminController.js

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

3. Her rota değişikliğinde doğrulamayı kontrol edin.

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

Alternatif olarak, kullanıcı nesnesi üzerinde izinler ayarlayabilir ve her rotaya bir izin atayabilir, ardından olay geri çağrısındaki izni kontrol edebilirsiniz.


@malcolmhall yup, bu kaydolmak istiyor ve çıkmak istiyorsun. Bunun yerine, giriş sayfası gibi genel rotalara "genel" bir boole ekleyin ve yönlendirinif (!user && !next.$$route.public)
AJcodez 11:15

Birisi next.$$routebana açıklayabilir mi? Açısal dokümanlarda, bir $routeChangeStartolaya verilen argümanları tanımlayan hiçbir şey bulamıyorum , ancak varsayıyorum nextve currbir tür konum nesnesi mi? $$routeBiraz google zordur.
skagedal

2
Şimdi $$routeözelliği Angular's özel bir değişken olduğunu görüyorum . Buna güvenmemelisiniz, örneğin bakınız: stackoverflow.com/a/19338518/1132101 - yaparsanız Açısal değiştiğinde kodunuz bozulabilir.
skagedal

2
Ben döngü bir özel mülkiyet erişmesini veya kalmadan rotayı erişmek için bir yol buldum $route.routes(@ thataustin yanıtında gibi) bir liste oluşturmak için: alan yer için yolunu almak next.originalPathbu indekse ve kullanım $route.routes: var auth = $route.routes[next.originalPath].
skagedal

Etkinliğe verilen argümanlar hakkındaki üç yorumdan önceki sorumu
skagedal

27

İşte böyle yaptım, kimseye yardım etmesi durumunda:

Yapılandırmada, publicAccessherkese açık olmasını istediğim birkaç rotada (giriş veya kayıt gibi) bir özellik ayarladım :

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

daha sonra bir çalışma bloğunda, kullanıcının erişimi yoksa veya rota herkese açık olmadığı sürece $routeChangeStartyönlendiren olayda bir dinleyici ayarladım '/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');
        }
    });
})

Durumu açıkça isLoggedInbaşka bir şeye değiştirebilirsin ... sadece bunu yapmanın başka bir yolunu göster.


ve çalışma bloğu bağımsız değişkenlerinizdeki kullanıcı nedir? servis?
mohamnag

Evet, kullanıcının oturum
açıp açmadığını

Rotaya nextLoc.$$route.publicAccessbtw gibi erişebilirsiniz .
AJcodez

Veya $route.routes[nextLoc.originalPath]özel değişken kullanmayan kullanın.
skagedal

1
Aslında, sadece kontrol edebilirsiniz nextLoc && nextLoc.publicAccess!
skagedal

9

Ben önleyici kullanarak yapıyorum. İndex.html dosyasına eklenebilecek bir kütüphane dosyası oluşturdum. Bu şekilde, geri kalan servis çağrılarınız için global hata işleme uygulayacak ve tüm hataları tek tek önemsemeniz gerekmeyecek. Daha sonra temel kimlik doğrulama giriş kütüphanemi de yapıştırdım. Orada da 401 hatasını kontrol ettiğimi ve farklı bir yere yönlendirdiğimi görebilirsiniz. Bkz. Lib / ea-basic-auth-login.js

lib / http-hata-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-hata-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-temel-yetkilisi login.js

Giriş için neredeyse aynı şey yapılabilir. Burada yeniden yönlendirmenin cevabı var ($ 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
Gerçekten bir direktif içinde sürece JS dom manipülasyon yapmaktan uzak durmalısınız. Bir mantık oluşturup ardından bir sınıf uygulamak ve bir CSS animasyonunu tetiklemek için ng-class kullanıyorsanız daha sonra kendinize teşekkür edersiniz.
Askdesigners

7

App.js dosyanızda:

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

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

4

Açısal-ui-yönlendirici ile başka bir görünüme yeniden yönlendirmek mümkündür . Bu amaçla yöntemimiz var $state.go("target_view"). Örneğin:

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

Açısal-ui-yönlendirici kullanmak istemiyorsanız, ancak denetleyicilerinizin RequireJS aracılığıyla tembel olarak yüklenmesini istiyorsanız, $routeChangeStartdenetleyicilerinizi RequireJS modülleri (tembel yüklü) olarak kullanırken olayla ilgili birkaç sorun vardır .

Tetiklemeden önce kontrolörün yükleneceğinden emin olamazsınız $routeChangeStart- aslında yüklenmeyecektir. Bu, nextrota gibi localsveya $$routehenüz ayarlanmadığı için rota özelliklerine erişemeyeceğiniz anlamına gelir .
Misal:

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

Bu, oradaki erişim haklarını kontrol edemeyeceğiniz anlamına gelir.

Çözüm:

Denetleyicinin yüklenmesi çözümleme yoluyla yapıldığından, aynı şeyi erişim kontrolü kontrolünüzle de yapabilirsiniz:

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

Yerine olayı kullanmanın burada dikkat $routeChangeStartkullanıyorum$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'});

Bu temel bir rota yapılandırmasıdır ... Konfigüre edilen rotalara yönlendirmeden önce herhangi bir koşulu nerede kontrol ediyoruz ..?
TJ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.