[Angularjs] إعادة التوجيه إلى مسار معين بناءً على شرط



Answers

قد يكون هنا حل أكثر أناقة ومرونة مع خاصية تكوين "التصميم" و "نعد" بتمكين تحميل البيانات في نهاية المطاف على قواعد التوجيه والتوجيه اعتمادا على البيانات.

يمكنك تحديد وظيفة في "حل" في تكوين التوجيه وفي تحميل الدالة والتحقق من البيانات ، قم بإجراء جميع عمليات إعادة التوجيه. إذا كنت بحاجة إلى تحميل البيانات ، فأنت تعيد الوعد ، إذا كنت بحاجة إلى القيام بعملية إعادة التوجيه - رفض الوعد قبل ذلك. يمكن العثور على كل التفاصيل على صفحات وثائق $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;
    }
};

للناس الناطقين بالروسية هناك وظيفة على habr " Вариант условного раутинга в AngularJS ."

Question

أكتب إليك تطبيق 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 فارغًا ثم أعد التوجيه إلى / تسجيل الدخول"

...

... انتظر هل يمكنني الاستماع إلى التغييرات الطريق بطريقة أو بأخرى؟ سأقوم بنشر هذا السؤال على أي حال واستمر بالنظر.




إليكم كيف فعلت ذلك ، في حال ساعدت أي شخص:

في التهيئة ، أقوم بتعيين سمة publicAccess على الطرق القليلة التي أريد 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 من isLoggedIn إلى أي شيء آخر ... فقط تظهر طريقة أخرى للقيام بذلك.




في ملف app.js الخاص بك:

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

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



هناك طريقة مختلفة لتنفيذ إعادة توجيه تسجيل الدخول وهي استخدام الأحداث والمعترضات كما هو موضح هنا . توضح هذه المقالة بعض المزايا الإضافية مثل اكتشاف وقت تسجيل الدخول ، وتسجيل الطلبات ، وإعادة عرضها بمجرد نجاح تسجيل الدخول.

يمكنك تجربة عرض تجريبي here وعرض المصدر التجريبي here .




من الممكن إعادة التوجيه إلى طريقة عرض أخرى باستخدام angular-ui-router . لهذا الغرض ، لدينا الأسلوب $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>



Links