Angularjs – annuleer de gebeurtenis van de route wijzigen

Hoe annuleer ik het routeverwijzingsevenement in Angularjs?

Mijn huidige code is

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

Hiermee, zelfs als de validatie faalt, hindert de volgende sjabloon en bijbehorende gegevens en schakelt vervolgens onmiddellijk terug naar de vorige weergave / route. Ik wil niet hoekig om volgende sjabloon & amp te trekken; Gegevens als validatie mislukt, idealiter zou er geen venster moeten zijn.History.Back (). Ik heb zelfs event.preventdefault () maar geen gebruik geprobeerd.


Antwoord 1, Autoriteit 100%

In plaats van $routeChangeStartGebruik $locationChangeStart

Hier is de discussie hierover van de Angularjs Guys: https://github.com/ hoekig / hoekig.js / problemen / 2109

Edit 3/6/2018 U kunt het vinden in de Documenten: Https://docs.angularjs.org/api/ng/service/$Location#Event-$LocationChangEstart

Voorbeeld:

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

Antwoord 2, Autoriteit 21%

Een meer complete codemonster, met behulp van $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); 
      });
    }
  );

Ik ben niet helemaal blij met het aansluiten van dit in mijn rootcontroller (Top Level Controller). Als er een beter patroon is, zou ik het graag willen weten. Ik ben nieuw in hoekig: -)


Antwoord 3, Autoriteit 7%

Een oplossing is om een ​​’notauthorized’-evenement uit te zenden en in de hoofdschema te vangen om de locatie opnieuw te veranderen. Ik denk dat het niet de beste oplossing is, maar het werkte voor mij:

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

en in mijn hoofdregelaar:

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

Opmerking: er is enige discussie over dit probleem op een hoekige site, nog niet opgelost:
https://github.com/angular/angular.js/pull/4192

bewerken:

Om de opmerking te beantwoorden, is hier meer informatie over de LoginService-werken. Het bevat 3 functies:

  1. Login () (naam is misleidend) Doe een verzoek aan de server om informatie over de (eerder) gelogde gebruiker te krijgen. Er is nog een inlogpagina die gewoon de huidige gebruikersstatus in de server vult (met behulp van Springcurity Framework). Mijn webservices zijn niet echt staatloos, maar ik liever dat het beroemde framework mijn beveiliging kan behandelen.
  2. Isauthentication () Zoeken als de clientsessie is gevuld met gegevens, wat betekent dat deze vóór (*)
  3. is geverifieerd

  4. is geautoriseerd () verwerkte toegangsrechten (buiten de reikwijdte voor dit onderwerp).

(*) Mijn sessie wordt ingevuld wanneer de route verandert. Ik heb de methode then when() overschreven om de sessie te vullen wanneer deze leeg is.

Hier is de code:

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

Antwoord 4, autoriteit 2%

Voor iedereen die dit tegenkomt is een oude vraag, (tenminste in hoek 1.4) kun je dit doen:

.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()
            }
        })
      })

Antwoord 5

Dit is mijn oplossing en het werkt voor mij, maar ik weet niet of ik op de goede weg ben, want ik ben nieuw in webtechnologieën.

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

Antwoord 6

ik vond deze relevant

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

mijn bericht kan iemand in de toekomst helpen.


Antwoord 7

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

Antwoord 8

In het geval dat u moet voorkomen dat de route verandert in de $routeChangeStart-gebeurtenis (dwz u wilt een bewerking uitvoeren op basis van de volgende route), injecteer $routeen binnen $routeChangeStartoproep:

$route.reload()

Antwoord 9

Gewoon om te delen, in mijn geval wil ik de oplossing van de route vertragenmet $routeChangeStart. Ik heb een SomethingService die moet worden geladen voordat de oplossing van de route begint (ja, spraakzame toepassing), vandaar dat ik een belofte heb om op te wachten. Misschien heb ik een hack gevonden… De oplossing van de route gaat fout als een oplossing een afwijzing retourneert. Ik heb de resolutie-configuratie verbroken en ik herstel het later weer.

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

Other episodes