Saya sedang mengerjakan aplikasi yang memiliki banyak peran sehingga saya perlu menggunakan penjaga untuk memblokir navigasi ke bagian aplikasi berdasarkan peran tersebut. Saya menyadari bahwa saya dapat membuat kelas penjaga individu untuk setiap peran, tetapi lebih suka memiliki satu kelas yang entah bagaimana dapat saya berikan parameter. Dengan kata lain, saya ingin bisa melakukan sesuatu yang serupa dengan ini:
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: [RoleGuard.forRole('superUser')]
}
Tetapi karena semua yang Anda lewati adalah nama tipe penjaga Anda, tidak dapat memikirkan cara untuk melakukan itu. Haruskah saya menggigit peluru dan menulis kelas penjaga individu per peran dan menghancurkan ilusi keanggunan saya dengan memiliki satu tipe parameter?
sumber
roles
objek dan penjaga rute terhubung tanpa mengetahui cara kerja kode sebelumnya. Sungguh menyebalkan bahwa Angular tidak mendukung cara untuk melakukan ini dengan cara yang lebih deklaratif. (Untuk memperjelas ini adalah saya meratapi Angular bukan solusi yang masuk akal ini.)Inilah pendapat saya tentang ini dan kemungkinan solusi untuk masalah penyedia yang hilang.
Dalam kasus saya, kami memiliki penjaga yang mengambil izin atau daftar izin sebagai parameter, tetapi itu hal yang sama memiliki peran.
Kami memiliki kelas untuk menangani penjaga autentikasi dengan atau tanpa izin:
Ini berkaitan dengan memeriksa sesi aktif pengguna, dll.
Ini juga berisi metode yang digunakan untuk mendapatkan penjaga izin khusus, yang sebenarnya bergantung pada
AuthGuardService
dirinya sendiriIni memungkinkan kami menggunakan metode untuk mendaftarkan beberapa penjaga khusus berdasarkan parameter izin di modul perutean kami:
Bagian yang menarik dari
forPermission
adalahAuthGuardService.guards.push
- ini pada dasarnya memastikan bahwa setiap saatforPermissions
dipanggil untuk mendapatkan kelas penjaga khusus, ia juga akan menyimpannya dalam larik ini. Ini juga statis di kelas utama:Kemudian kita dapat menggunakan larik ini untuk mendaftarkan semua penjaga - tidak apa-apa selama kita memastikan bahwa pada saat modul aplikasi mendaftarkan penyedia ini, rute telah ditentukan dan semua kelas penjaga telah dibuat (misalnya, periksa urutan impor dan pertahankan penyedia ini serendah mungkin dalam daftar - memiliki modul perutean membantu):
Semoga ini membantu.
sumber
ERROR in Error during template compile of 'RoutingModule' Function calls are not supported in decorators but 'PermGuardService' was called.
Solusi @ AluanHaddad adalah memberikan kesalahan "tidak ada penyedia". Berikut ini cara memperbaikinya (rasanya kotor, tetapi saya kurang memiliki keterampilan untuk membuatnya lebih baik).
Secara konseptual, saya mendaftar, sebagai penyedia, setiap kelas yang dibuat secara dinamis dibuat oleh
roleGuard
.Jadi untuk setiap peran yang diperiksa:
Kamu harus punya:
Namun, solusi @ AluanHaddad apa adanya akan menghasilkan kelas baru untuk setiap panggilan ke
roleGuard
, meskipunroles
parameternya sama. Menggunakannyalodash.memoize
terlihat seperti ini:Perhatikan, setiap kombinasi peran menghasilkan kelas baru, jadi Anda perlu mendaftar sebagai penyedia setiap kombinasi peran. Yaitu jika Anda memiliki:
canActivate: [roleGuard('foo')]
dancanActivate: [roleGuard('foo', 'bar')]
Anda harus mendaftarkan keduanya:providers[roleGuard('foo'), roleGuard('foo', 'bar')]
Solusi yang lebih baik adalah mendaftarkan penyedia secara otomatis dalam kumpulan penyedia global di dalamnya
roleGuard
, tetapi seperti yang saya katakan, saya kurang memiliki keterampilan untuk mengimplementasikannya.sumber