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

...

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




من الممكن إعادة التوجيه إلى طريقة عرض أخرى باستخدام 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>



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

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

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



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

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




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

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




Related