AngularJs - anulowanie zdarzenia zmiany trasy


Jak anulować zdarzenie zmiany trasy w AngularJs?
Mój obecny kod to
$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 }
});

dzięki temu, nawet jeśli walidacja się nie powiedzie, Angular pobiera następny szablon i powiązane dane, a następnie natychmiast przełącza się z powrotem do poprzedniego widoku/trasy. nie chcę, aby kątowy ciągnął następujący szablon & amp; data, jeśli walidacja się nie powiedzie, najlepiej byłoby, gdyby nie było metody window.history.back (). Próbowałem nawet event.preventDefault (), ale bezskutecznie.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zamiast
$ routeChangeStart
użyj
$ locationChangeStart
Oto dyskusja na ten temat od facetów z angularjs:

https://github.com/angular/angular.js/issues/2109
https://github.com/angular/angular.js/issues/2109

Edycja 06.03.2018

można go znaleźć w dokumentacji:

https://docs.angularjs.org/api/ng/service/$ lokalizacja wydarzenia - $ # locationChangeStart
https://docs.angularjs.org/api/ng/service/$location#event-$locationChangeStart
Przykład:
$scope.$on('$locationChangeStart', function(event, next, current) {
if ($scope.form.$invalid) {
event.preventDefault();
}
});
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Bardziej kompletny przykład kodu z użyciem
$ 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);
});
}
);

Nie jestem do końca zadowolony z podłączenia tego do mojego kontrolera głównego (kontrolera najwyższego poziomu). Czy istnieje lepsza próbka, którą chciałbym poznać. Jestem nowy w Angular :-)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Rozwiązaniem jest nadanie zdarzenia „notAuthorized” i przechwycenie go w głównym zakresie, aby ponownie zmienić jego położenie. Myślę, że to nie jest najlepsze rozwiązanie, ale u mnie zadziałało:
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');
}
}
});
}
]);

aw moim głównym kontrolerze:
$scope.$on('notAuthorized', function(){
$location.path('/forbidden');
});

Uwaga: istnieje dyskusja na temat tego problemu w witrynie kątowej, która nie została jeszcze rozwiązana:

https://github.com/angular/angular.js/pull/4192
https://github.com/angular/angular.js/pull/4192

EDIT

:
Aby odpowiedzieć na komentarz, oto więcej szczegółów na temat działania usługi LoginService. Zawiera 3 funkcje:
  • login () (nazwa jest myląca) wysyła do serwera żądanie uzyskania informacji o (wcześniej) zalogowanym użytkowniku. Istnieje inna strona logowania, która po prostu wypełnia bieżący stan użytkownika na serwerze (przy użyciu struktury SpringSecurity). Moje usługi internetowe nie są tak naprawdę bezpaństwowe, ale wolałem tę słynną platformę do zarządzania moimi zabezpieczeniami.
  • isAuthenticated () po prostu wyszukuje, czy sesja klienta jest pełna danych, co oznacza, że ​​została uwierzytelniona wcześniej (*)
  • isAuthorized () przetworzone prawa dostępu (poza zakresem tej sekcji).

(*) Moja sesja zapełnia się przy zmianie trasy. Zastąpiłem metodę then when (), aby wypełnić sesję, gdy jest pusta.
Oto kod:
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'
});
}]);
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dla każdego, kto natknie się na to stare pytanie (przynajmniej w kątowym 1.4), możesz zrobić to:
.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()
}
})
})
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To jest moje rozwiązanie i działa dla mnie, ale nie wiem, czy jestem na dobrej drodze, ponieważ jestem nowy w technologii internetowej.
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
});
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

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

Anonimowy użytkownik

Potwierdzenie od:

uznałem to za stosowne
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()
});
});

mój post może pomóc komuś w przyszłości.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W przypadku, gdy musisz zatrzymać trasę przed zmianą w zdarzeniu
$ routeChangeStart
(tj. Chcesz zrobić

operacja oparta na następnej trasie
), wpisz
$ route
i zadzwoń wewnątrz
$ routeChangeStart
:
$route.reload()

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się