Bagaimana cara membatalkan acara perubahan rute di AngularJs?
Kode saya saat ini adalah
$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
}
});
dengan ini bahkan jika validasi gagal Angular menarik template berikutnya dan data terkait dan kemudian segera beralih kembali ke tampilan / rute sebelumnya. Saya tidak ingin angular menarik template & data berikutnya jika validasi gagal, idealnya tidak ada window.history.back (). Saya bahkan mencoba event.preventDefault () tetapi tidak ada gunanya.
javascript
angularjs
R Arun
sumber
sumber
$routeChangeStart
yangnext
variabel hanya string dan tidak dapat berisi data (misalnya Anda tidak dapat akses ke didefinisikan sebelumnyaauthorizedRoles
variabel)$location.path()
dan$location.search()
Contoh kode yang lebih lengkap, menggunakan
$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); }); } );
Saya tidak sepenuhnya senang dengan menghubungkan ini di pengontrol root saya (pengontrol tingkat atas). Jika ada pola yang lebih baik, saya ingin tahu. Saya baru mengenal angular :-)
sumber
Solusinya adalah menyiarkan acara 'notAuthorized', dan menangkapnya di ruang lingkup utama untuk mengubah ulang lokasi. Saya pikir ini bukan solusi terbaik, tetapi berhasil untuk saya:
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'); } } }); } ]);
dan di Pengontrol Utama saya:
$scope.$on('notAuthorized', function(){ $location.path('/forbidden'); });
Catatan: Ada beberapa diskusi tentang masalah ini di situs sudut, belum terpecahkan: https://github.com/angular/angular.js/pull/4192
EDIT:
Untuk menjawab komentar tersebut, berikut adalah informasi lebih lanjut tentang cara kerja LoginService. Ini berisi 3 fungsi:
(*) Sesi Saya diisi saat rute berubah. Saya telah mengganti metode then when () untuk mengisi sesi saat kosong.
Ini kodenya:
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' }); }]);
sumber
LoginService.isAuthenticated()
saat memuat halaman pertama? Bagaimana Anda menyimpancurrentUser
? Apa yang terjadi jika pengguna menyegarkan halaman (pengguna perlu memasukkan kembali kredensial)?Bagi siapa pun yang tersandung pada ini adalah pertanyaan lama, (setidaknya dalam sudut 1.4) Anda dapat melakukan ini:
.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() } }) })
sumber
Ini adalah solusi saya dan berfungsi untuk saya tetapi saya tidak tahu apakah saya berada di jalan yang benar karena saya baru mengenal teknologi web.
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 });
sumber
saya menemukan yang satu ini relevan
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() }); });
posting saya mungkin membantu seseorang di masa depan.
sumber
var app=angular .module('myapp', []) .controller('myctrl', function($rootScope) { $rootScope.$on("locationChangeStart", function(event, next, current) { if (!confirm("location changing to:" + next)) { event.preventDefault(); } }) });
sumber
Jika Anda perlu menghentikan rute agar tidak berubah dalam
$routeChangeStart
acara (yaitu Anda ingin melakukan beberapa operasi berdasarkan rute berikutnya ), injeksi$route
dan$routeChangeStart
panggilan dalam :sumber
$route.reload()
harus berbeda atau menjalankan kode yang sama lagi. Ini sama dengan membuatwhile
loop dengantrue
sebagai kondisi.Sekadar berbagi, dalam kasus saya, saya ingin menunda resolusi rute dengan $ routeChangeStart. Saya punya SomethingService yang harus dimuat sebelum resolusi rute dimulai (ya, aplikasi cerewet) maka saya punya janji untuk menunggu. Mungkin saya menemukan peretasan ... Resolusi rute mengalami kesalahan jika penyelesaian mengembalikan penolakan. Saya merusak konfigurasi penyelesaian dan saya memperbaikinya kembali nanti.
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; } });
sumber