AngularJs - রুট পরিবর্তন ইভেন্ট বাতিল করুন


88

অ্যাংুলারজেজে আমি কীভাবে রুট পরিবর্তন ইভেন্ট বাতিল করব?

আমার বর্তমান কোডটি

$rootScope.$on("$routeChangeStart", function (event, next, current) {

// do some validation checks
if(validation checks fails){

    console.log("validation failed");

    window.history.back(); // Cancel Route Change and stay on current page  

}
});

এটি সহ যদি বৈধতা ব্যর্থ হয় তবে কৌনিকটি পরবর্তী টেম্পলেট এবং সম্পর্কিত ডেটা টেনে নেয় এবং তারপরে তাত্ক্ষণিকভাবে পূর্ববর্তী ভিউ / রুটে ফিরে যায়। বৈধতা ব্যর্থ হলে পরবর্তী টেম্পলেট এবং ডেটা টানতে আমি কৌনিক চাই না, আদর্শভাবে উইন্ডো হিস্টোরি.ব্যাক () থাকতে হবে না। এমনকি আমি ইভেন্ট.প্রিভেন্টডিফল্ট () চেষ্টা করেও ব্যবহার করি না।

উত্তর:


184

পরিবর্তে $routeChangeStartব্যবহার$locationChangeStart

এটি সম্পর্কে কৌণিকুল ছেলেরা থেকে আলোচনাটি এখানে রয়েছে: https://github.com/angular/angular.js/issues/2109

3/6/2018 সম্পাদনা করুন আপনি এটি ডক্সে এটি পেতে পারেন: https://docs.angularjs.org/api/ng/service/$location#event-$locationChangeStart

উদাহরণ:

$scope.$on('$locationChangeStart', function(event, next, current) {
    if ($scope.form.$invalid) {
       event.preventDefault();
    }
});

8
এটির সাথে সমস্যা হ'ল রুট পরামিতি সংগ্রহের অ্যাক্সেসের কোনও উপায় নেই। আপনি যদি রুটের পরামিতিগুলিকে বৈধতা দেওয়ার চেষ্টা করছেন তবে এই সমাধানটি ভাল নয়।
কিংঅফ হাইপোক্রিটিস 30-22 এ

4
দয়া করে নোট করুন, ভেরিয়েবলটি ব্যবহার $routeChangeStartকরার সময় nextকেবল একটি স্ট্রিং থাকে এবং এতে কোনও ডেটা থাকতে পারে না (উদাহরণস্বরূপ আপনি পূর্বনির্ধারিত authorizedRolesভেরিয়েবলটি অ্যাক্সেস করতে পারবেন না )
মাইটিটল

কিংগফ হাইপোক্রিটস আপনি রুটের প্যারামিটারগুলি পেতে পারেন না তবে আপনি পেতে পারেন $location.path()এবং$location.search()
অ্যাড্রিয়ান

4
আপনি যদি সমস্ত রুটের পরিবর্তনগুলি ট্র্যাক করতে চান তবে আপনি / rootScope এ এটি করার পরামর্শ দেওয়া যেতে পারে? বা আরও কি স্বচ্ছ বিকল্প আছে?
সর্বোচ্চ

38

ব্যবহার করে আরও একটি সম্পূর্ণ কোড নমুনা $locationChangeStart

// assuming you have a module called app, with a 
angular.module('app')
  .controller(
    'MyRootController',
    function($scope, $location, $rootScope, $log) {
      // your controller initialization here ...
      $rootScope.$on("$locationChangeStart", function(event, next, current) { 
        $log.info("location changing to:" + next); 
      });
    }
  );

এটিকে আমার রুট কন্ট্রোলারে (শীর্ষ স্তরের নিয়ামক) হুক করে আমি পুরোপুরি খুশি নই। যদি আরও ভাল প্যাটার্ন থাকে তবে আমি তা জানতে আগ্রহী। আমি কৌনিকটি নতুন :-)


এটি আমার পক্ষে দুর্দান্ত কাজ করেছে, যদিও আমি মূল পোস্টারের মতো আমার রুট পরিবর্তন বাতিল করার চেষ্টা করছি না। ধন্যবাদ!
জিম ক্লাউজ

4
হ্যাঁ রুটস্কোপের সমস্যা হ'ল আপনার কন্ট্রোলারটি চলে যাওয়ার পরে আপনাকে সেই হ্যান্ডলারটি বাঁধাই করতে হবে।
ট্রান্সলেশন

12

একটি সমাধান হ'ল 'অনুমোদিত নয়' ইভেন্টটি সম্প্রচার করা এবং অবস্থানটি পুনরায় পরিবর্তন করার জন্য এটি মূল সুযোগে ধরা। আমি মনে করি এটি সেরা সমাধান নয়, তবে এটি আমার পক্ষে কাজ করেছে:

myApp.run(['$rootScope', 'LoginService',
    function ($rootScope, LoginService) {
        $rootScope.$on('$routeChangeStart', function (event, next, current) {
            var authorizedRoles = next.data ? next.data.authorizedRoles : null;
            if (LoginService.isAuthenticated()) {
                if (!LoginService.isAuthorized(authorizedRoles)) {
                    $rootScope.$broadcast('notAuthorized');
                }
            }
        });
    }
]);

এবং আমার প্রধান নিয়ামক:

    $scope.$on('notAuthorized', function(){
        $location.path('/forbidden');
    });

দ্রষ্টব্য: কৌণিক সাইটে এই সমস্যাটি নিয়ে কিছু আলোচনা রয়েছে, এখনও সমাধান হয়নি: https://github.com/angular/angular.js/pull/4192

সম্পাদনা:

মন্তব্যের জবাব দেওয়ার জন্য, এখানে লগইন সার্ভিস সম্পর্কে আরও তথ্য কাজ করা আছে। এটিতে 3 টি কার্য রয়েছে:

  1. লগইন () (নামটি বিভ্রান্তিমূলক) লগ-ইন করা ব্যবহারকারী সম্পর্কে তথ্য পেতে সার্ভারের কাছে একটি অনুরোধ করে। এখানে আরও একটি লগইন পৃষ্ঠা রয়েছে যা কেবলমাত্র বর্তমান ব্যবহারকারী অবস্থাটি সার্ভারে সজ্জিত করে (স্প্রিংসিকিউরিটি ফ্রেমওয়ার্ক ব্যবহার করে) আমার ওয়েব পরিষেবাদি সত্যই রাষ্ট্রহীন নয়, তবে আমি সেই বিখ্যাত কাঠামোটিকে আমার সুরক্ষা পরিচালনা করতে দেওয়া পছন্দ করেছিলাম preferred
  2. #Anthenticated () ক্লায়েন্ট সেশনটি ডেটা ভরাট করা সন্ধান করুন, যার অর্থ এটি আগে (*) প্রমাণীকরণ করা হয়েছে
  3. isAuthorised () হ্যান্ডেল অ্যাক্সেস রাইটস (এই বিষয়টির সুযোগের বাইরে)।

(*) রুট পরিবর্তন হলে আমার সেশনটি জনবহুল হয়। আমি তখন () পদ্ধতিটি ফাঁকা হয়ে গেলে সেশনটি পপুলেট করার জন্য ওভাররাইড করেছি।

কোডটি এখানে:

services.factory('LoginService', ['$http', 'Session', '$q',
function($http, Session, $q){
    return {
        login: function () {
            var defer = $q.defer();
            $http({method: 'GET', url: restBaseUrl + '/currentUser'})
                .success(function (data) {
                    defer.resolve(data);
                });
            return defer.promise;
        },
        isAuthenticated: function () {
            return !!Session.userLogin;
        },
        isAuthorized: function (authorizedRoles) {
            if (!angular.isArray(authorizedRoles)) {
                authorizedRoles = [authorizedRoles];
            }

            return (this.isAuthenticated() &&  authorizedRoles.indexOf(Session.userRole) !== -1);
        }
    };
}]);

myApp.service('Session', ['$rootScope',
    this.create = function (userId,userLogin, userRole, userMail, userName, userLastName, userLanguage) {
        //User info
        this.userId = userId;
        this.userLogin = userLogin;
        this.userRole = userRole;
        this.userMail = userMail;
        this.userName = userName;
        this.userLastName = userLastName;
        this.userLanguage = userLanguage;
    };

    this.destroy = function () {
        this.userId = null;
        this.userLogin = null;
        this.userRole = null;
        this.userMail = null;
        this.userName = null;
        this.userLastName = null;
        this.userLanguage = null;
        sessionStorage.clear();
    };

    return this;
}]);

myApp.config(['$routeProvider', 'USER_ROLES', function ($routeProvider, USER_ROLES) {
    $routeProvider.accessWhen = function (path, route) {
        if (route.resolve == null) {
            route.resolve = {
                user: ['LoginService','Session',function (LoginService, Session) {
                    if (!LoginService.isAuthenticated())
                        return LoginService.login().then(function (data) {
                            Session.create(data.id, data.login, data.role, data.email, data.firstName, data.lastName, data.language);
                            return data;
                        });
                }]
            }
        } else {
            for (key in route.resolve) {
                var func = route.resolve[key];
                route.resolve[key] = ['LoginService','Session','$injector',function (LoginService, Session, $injector) {
                    if (!LoginService.isAuthenticated())
                        return LoginService.login().then(function (data) {
                            Session.create(data.id, data.login, data.role, data.email, data.firstName, data.lastName, data.language);
                            return func(Session, $injector);
                        });
                    else
                        return func(Session, $injector);
                }];
            }
        }
    return $routeProvider.when(path, route);
    };

    //use accessWhen instead of when
    $routeProvider.
        accessWhen('/home', {
            templateUrl: 'partials/dashboard.html',
            controller: 'DashboardCtrl',
            data: {authorizedRoles: [USER_ROLES.superAdmin, USER_ROLES.admin, USER_ROLES.system, USER_ROLES.user]},
            resolve: {nextEvents: function (Session, $injector) {
                $http = $injector.get('$http');
                return $http.get(actionBaseUrl + '/devices/nextEvents', {
                    params: {
                        userId: Session.userId, batch: {rows: 5, page: 1}
                    },
                    isArray: true}).then(function success(response) {
                    return response.data;
                });
            }
        }
    })
    ...
    .otherwise({
        redirectTo: '/home'
    });
}]);

আপনি দয়া করে বলতে পারেন LoginService.isAuthenticated()প্রথম পৃষ্ঠার লোডিংয়ে কী ফিরবে ? আপনি কিভাবে সংরক্ষণ করছেন currentUser? ব্যবহারকারী পৃষ্ঠাটি রিফ্রেশ করলে (ব্যবহারকারীর শংসাপত্র পুনরায় প্রবেশের প্রয়োজন হলে) কী হবে?
MyTitle

আমি আমার আসল উত্তরে লগইন সার্ভিস সম্পর্কে আরও তথ্য যুক্ত করেছি। বর্তমান ব্যবহারকারী সার্ভার দ্বারা সরবরাহ করা হয়েছে, এবং রুট পরিবর্তন যে কোনও পৃষ্ঠা রিফ্রেশ পরিচালনা করে, ব্যবহারকারীর আবার লগ ইন করার প্রয়োজন হয় না।
অ্যাসেরিয়াস

4

যে কেউ এ নিয়ে হোঁচট খাচ্ছে তাদের পক্ষে একটি পুরানো প্রশ্ন, (কমপক্ষে কৌণিক 1.4 তে) আপনি এটি করতে পারেন:

 .run(function($rootScope, authenticationService) {
        $rootScope.$on('$routeChangeStart', function (event, next) {
            if (next.require == undefined) return

            var require = next.require
            var authorized = authenticationService.satisfy(require);

            if (!authorized) {
                $rootScope.error = "Not authorized!"
                event.preventDefault()
            }
        })
      })

6
আমি ভাবছি, আপনি কি ধনুর্বন্ধনী ব্যবহারের জন্য অতিরিক্ত চার্জ পাবেন বা ";"?
সেল তীক্ষ্ণ

6
@ মাথিয়াসজ্যানসন অবশ্যই এবং এটি সর্বোপরি, ব্রেসগুলি দ্বিগুণ গণনা করে, এবং সেমিকোলনগুলি ট্রিপল গণনা করে।
osকোস ভান্ড্রা

1

এটি আমার সমাধান এবং এটি আমার পক্ষে কাজ করে তবে আমি জানি না যে আমি সঠিক প্রযুক্তির কারণে আমি ওয়েব প্রযুক্তিতে নতুন।

var app = angular.module("app", ['ngRoute', 'ngCookies']);
app.run(function($rootScope, $location, $cookieStore){
$rootScope.$on('$routeChangeStart', function(event, route){
    if (route.mustBeLoggedOn && angular.isUndefined($cookieStore.get("user"))) {
        // reload the login route
        jError(
             'You must be logged on to visit this page',
             {
               autoHide : true,
               TimeShown : 3000,
               HorizontalPosition : 'right',
               VerticalPosition : 'top',
               onCompleted : function(){ 
               window.location = '#/signIn';
                 window.setTimeout(function(){

                 }, 3000)
             }
        });
    }
  });
});

app.config(function($routeProvider){
$routeProvider
    .when("/signIn",{
        controller: "SignInController",
        templateUrl: "partials/signIn.html",
        mustBeLoggedOn: false
});

4
আপনি নিজের উত্তর সম্পর্কে নিশ্চিত না হলে কীভাবে কোনও প্রশ্নের উত্তর দিতে পারেন?
deW1

আমি নিশ্চিত যে এটি কার্যকর। আমি নিশ্চিত নই যে এটি সঠিক উপায় কিনা। আপনার যদি আরও ভাল সমাধান হয় তবে আমি এটি দেখতে চাই।
আলেকজান্দ্রাকিস আলেকজান্দ্রোস

1

আমি এটিকে প্রাসঙ্গিক বলে মনে করেছি

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

myApp.run(function($rootScope) {
    $rootScope.$on("$locationChangeStart", function(event, next, current) { 
        // handle route changes  
$rootScope.error = "Not authorized!"
                event.preventDefault()   
    });
});

আমার পোস্ট ভবিষ্যতে কাউকে সাহায্য করতে পারে।


1
var app=angular
    .module('myapp', [])
    .controller('myctrl', function($rootScope) {
        $rootScope.$on("locationChangeStart", function(event, next, current) {
        if (!confirm("location changing to:" + next)) { 
            event.preventDefault();
        }
    })
});

4
এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, যদিও সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
ডিআরপি

0

$routeChangeStartইভেন্টে রুটটি পরিবর্তন করতে আপনাকে থামাতে হবে (যেমন আপনি পরবর্তী রুটের উপর ভিত্তি করে কিছু অপারেশন করতে চান ), ইনজেকশন $routeএবং ভিতরে $routeChangeStartকল করুন:

$route.reload()

4
আমি আশাবাদী ছিলাম, তবে Chrome এ কৌণিক 1.2.2 এ এটি একটি জেএস লুপের কারণ বলে মনে হচ্ছে এবং পৃষ্ঠাটি হিমশীতল।
নিক স্পেস্ক

4
@ নিকস্পেসেক যে অবস্থাতে আপনি কল করেছেন তার অবস্থা $route.reload()আলাদা হওয়া দরকার অন্যথায় এটি আবার একই কোড চালাচ্ছে। এটি শর্ত হিসাবে whileলুপ তৈরির সমতুল্য true
কেভিন বিয়াল 17

0

কেবল ভাগ করে নেওয়ার জন্য, আমার ক্ষেত্রে আমি $ রুট চেঞ্জস্টার্ট দিয়ে রুট রেজোলিউশনটি বিলম্ব করতে চাই । আমার একটি সামিথ সার্ভিস রয়েছে যা রুটের রেজ্যুলেশন শুরুর আগে অবশ্যই লোড হবে (হ্যাঁ, চ্যাটি অ্যাপ্লিকেশন) সুতরাং আমি অপেক্ষা করার প্রতিশ্রুতি পেয়েছি। হতে পারে আমি একটি হ্যাক পেয়েছি ... কোনও সমাধান যদি প্রত্যাখান প্রত্যাবর্তন করে তবে রুটের রেজোলিউশনটি ত্রুটিযুক্ত হয়। আমি সমাধানের কনফিগারেশনটি ভেঙে দিয়েছি এবং পরে এটি ঠিক করেছি।

    var rejectingResolve = {
        cancel: function ($q){
            // this will cancel $routeChangeStart
            return $q.reject();
        }
    }
    
    $rootScope.$on("$routeChangeStart", function(event, args, otherArgs) {
        var route = args.$$route,
            originalResolve = route.resolve;
    
        if ( ! SomethingService.isLoaded() ){

            SomethingService.load().then(function(){
                // fix previously destroyed route configuration
                route.resolve = originalResolve;
                
                $location.search("ts", new Date().getTime());
                // for redirections
                $location.replace();
            });

            // This doesn't work with $routeChangeStart: 
            // we need the following hack
            event.preventDefault();
            
            // This is an hack! 
            // We destroy route configuration, 
            // we fix it back when SomethingService.isLoaded
            route.resolve = rejectingResolve;
        } 
    });
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.