Saya sedang menulis aplikasi AngularJS kecil yang memiliki tampilan masuk dan tampilan utama, dikonfigurasi seperti:
$routeProvider
.when('/main' , {templateUrl: 'partials/main.html', controller: MainController})
.when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
.otherwise({redirectTo: '/login'});
LoginController saya memeriksa kombinasi pengguna / pass dan menetapkan properti pada $ rootScope yang mencerminkan ini:
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.";
}
}
Semuanya berfungsi, tetapi jika saya mengakses http://localhost/#/main
saya akhirnya melewati layar login. Saya ingin menulis sesuatu seperti "setiap kali rute berubah, jika $ rootScope.loggedUser adalah null maka redirect ke / login"
...
... tunggu. Bisakah saya mendengarkan perubahan rute entah bagaimana? Saya akan tetap mengirimkan pertanyaan ini dan terus mencari.
Jawaban:
Setelah beberapa menyelam melalui beberapa dokumentasi dan kode sumber, saya pikir saya berhasil. Mungkin ini akan bermanfaat bagi orang lain?
Saya menambahkan yang berikut ini ke konfigurasi modul saya:
Satu hal yang tampaknya aneh adalah bahwa saya harus menguji nama parsial (
login.html
) karena objek Route "berikutnya" tidak memiliki url atau sesuatu yang lain. Mungkin ada cara yang lebih baik?sumber
Berikut ini mungkin solusi yang lebih elegan dan fleksibel dengan properti konfigurasi 'tekad' dan 'janji' yang memungkinkan pemuatan data akhir pada aturan routing dan routing tergantung pada data.
Anda menentukan fungsi dalam 'menyelesaikan' dalam konfigurasi rute dan pada fungsi memuat dan memeriksa data, lakukan semua pengalihan. Jika Anda perlu memuat data, Anda mengembalikan janji, jika Anda perlu melakukan redirect - tolak janji sebelumnya. Semua detail dapat ditemukan di $ routerProvider dan halaman dokumentasi $ q .
Untuk orang-orang berbahasa Rusia ada posting di habr " Вариант условного раутинга в AngularJS ."
sumber
ui.router
digunakan, gunakan$stateProvider
sebagai ganti$routeProvider
.Saya telah mencoba melakukan hal yang sama. Datang dengan solusi sederhana lain setelah bekerja dengan seorang rekan. Saya memiliki jam tangan yang sudah diatur
$location.path()
. Itu yang berhasil. Saya baru mulai belajar AngularJS dan menemukan ini menjadi lebih bersih dan mudah dibaca.sumber
Cara berbeda untuk menerapkan pengalihan login adalah dengan menggunakan acara dan pencegat seperti yang dijelaskan di sini . Artikel ini menjelaskan beberapa keuntungan tambahan seperti mendeteksi kapan login diperlukan, mengantri permintaan, dan memutarnya kembali setelah login berhasil.
Anda dapat mencoba demo yang berfungsi di sini dan melihat sumber demo di sini .
sumber
1. Tetapkan pengguna global saat ini.
Di layanan otentikasi Anda, setel pengguna yang saat ini diautentikasi pada cakupan root.
2. Atur fungsi auth pada setiap rute yang dilindungi.
3. Periksa auth pada setiap perubahan rute.
Sebagai alternatif, Anda dapat mengatur izin pada objek pengguna dan memberikan izin pada setiap rute, lalu memeriksa izin dalam panggilan balik acara.
sumber
if (!user && !next.$$route.public)
next.$$route
kepada saya? Saya tidak menemukan apa pun dalam dokumen Sudut yang menjelaskan argumen yang diberikan pada suatu$routeChangeStart
peristiwa, tetapi saya berasumsinext
dancurr
apakah ada semacam objek lokasi? The$$route
bit sulit untuk google.$$route
properti adalah variabel pribadi Angular. Anda seharusnya tidak mengandalkan itu, lihat misalnya: stackoverflow.com/a/19338518/1132101 - jika Anda melakukannya, kode Anda mungkin rusak ketika perubahan Angular.$route.routes
untuk membangun daftar (seperti dalam jawaban @ thataustin ini): mendapatkan jalan untuk lokasi dengannext.originalPath
dan menggunakan itu untuk indeks$route.routes
:var auth = $route.routes[next.originalPath]
.Begini cara saya melakukannya, kalau-kalau itu membantu siapa pun:
Di konfigurasi, saya menetapkan
publicAccess
atribut pada beberapa rute yang ingin saya buka untuk umum (seperti login atau daftar):kemudian dalam menjalankan blok, saya menetapkan pendengar pada
$routeChangeStart
acara yang dialihkan ke'/login'
kecuali pengguna memiliki akses atau rute dapat diakses secara publik:Anda jelas dapat mengubah kondisi dari yang
isLoggedIn
lain ... hanya menunjukkan cara lain untuk melakukannya.sumber
nextLoc.$$route.publicAccess
btw.$route.routes[nextLoc.originalPath]
, yang tidak menggunakan variabel pribadi.nextLoc && nextLoc.publicAccess
!Saya melakukannya menggunakan pencegat. Saya telah membuat file perpustakaan yang dapat ditambahkan ke file index.html. Dengan cara ini Anda akan memiliki penanganan kesalahan global untuk panggilan layanan lainnya dan tidak perlu peduli tentang semua kesalahan secara individual. Lebih jauh ke bawah saya juga menempelkan perpustakaan login autentik dasar saya. Di sana Anda dapat melihat bahwa saya juga memeriksa kesalahan 401 dan mengalihkan ke lokasi yang berbeda. Lihat lib / ea-basic-auth-login.js
lib / http-error-handling.js
css / http-error-handling.css
index.html
lib / ea-basic-auth-login.js
Hampir sama bisa dilakukan untuk login. Di sini Anda memiliki jawaban untuk pengalihan ($ location.path ("/ login")).
sumber
Dalam file app.js Anda:
sumber
Dimungkinkan untuk mengalihkan ke tampilan lain dengan angular-ui-router . Untuk tujuan ini, kami memiliki metode
$state.go("target_view")
. Sebagai contoh:sumber
Jika Anda tidak ingin menggunakan angular-ui-router, tetapi ingin agar controller Anda dimuat melalui RequireJS, ada beberapa masalah dengan kejadian
$routeChangeStart
ketika menggunakan controller Anda sebagai modul RequireJS (lazy loaded).Anda tidak dapat memastikan pengontrol akan dimuat sebelum
$routeChangeStart
dipicu - sebenarnya itu tidak akan dimuat. Itu berarti Anda tidak dapat mengakses propertinext
seperti rutelocals
atau$$route
karena mereka belum diatur.Contoh:
Ini berarti Anda tidak dapat memeriksa hak akses di sana.
Larutan:
Karena memuat pengontrol dilakukan melalui tekad, Anda dapat melakukan hal yang sama dengan pemeriksaan kontrol akses Anda:
Perhatikan di sini bahwa alih-alih menggunakan acara yang
$routeChangeStart
saya gunakan$routeChangeError
sumber
sumber