Übergeben Sie parameter in der route guard
Arbeite ich an einer app, die eine Menge von Rollen, die ich verwenden müssen, die Wachen zu blockieren, die navigationssteuerung, um Teile der app basierend auf diesen Rollen. Ich weiß, ich kann einzelne Wache Klassen für jede Rolle, würde aber eher eine Klasse, die konnte ich irgendwie übergeben Sie einen parameter an. In anderen Worten: ich möchte in der Lage sein, etwas zu tun ähnlich wie diese:
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: [RoleGuard.forRole('superUser')]
}
Aber da alles, was Sie übergeben, ist der name Ihrer Wache, kann nicht denken Sie an einen Weg, das zu tun. Soll ich einfach bisschen die Kugel und schreiben der einzelnen Klassen guard pro Rolle und zerbrechen meine illusion von Eleganz, mit einer einzigen parametrisierten Typ statt?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie dies tun.
Statt mit
forRole()
sind, sollten Sie die Nutzung dieser:und verwenden Sie diese in Ihrem RoleGuard
roles
Objekt und die route guard verknüpft sind, ohne zu wissen, wie der code funktioniert, vor der Zeit. Es nervt, dass Eckig nicht unterstützt, ist ein Weg, dies zu tun in einer deklarativer Weise. (Zu sein klar, das ist mir beklagt Winkel nicht diese durchaus vernünftige Lösung.)Hier ist mein nehmen auf diese und eine mögliche Lösung für die fehlenden provider Problem.
In meinem Fall, wir haben einen Wächter, der braucht eine Erlaubnis oder eine Liste von Berechtigungen als parameter, aber es ist die gleiche Sache hat mit eine Rolle.
Haben wir eine Klasse für den Umgang mit auth Wachen mit oder ohne Erlaubnis:
Diese befasst sich mit der überprüfung Benutzer aktive Sitzungen, etc.
Es enthält auch eine Methode verwendet, um eine benutzerdefinierte Berechtigung guard, das ist sogar abhängig von der
AuthGuardService
sichDies ermöglicht es uns, verwenden Sie die Methode zum registrieren einige eigene Wachen basierend auf den Berechtigungen parameter in unserer routing-Modul:
Der interessante Teil
forPermission
istAuthGuardService.guards.push
- diese im Grunde stellt sicher, dass jederzeitforPermissions
aufgerufen wird, erhalten Sie eine eigene Wache-Klasse es wird auch speichern Sie Sie in diesem array. Dies ist auch statisch in der main-Klasse:Dann wir können dieses array verwenden, um zu registrieren, alle Wachen - das ist ok, solange wir sicherstellen, dass durch die Zeit, die die app-Modul registriert, diese Anbieter, die Routen definiert war und alle guard-Klassen geschaffen worden (z.B. Scheck-import-Ordnung und halten diese Anbieter so niedrig wie möglich in der Liste - mit einem routing-Modul hilft):
Hoffe, das hilft.
ERROR in Error during template compile of 'RoutingModule' Function calls are not supported in decorators but 'PermGuardService' was called.
@AluanHaddad s Lösung ist die Angabe "kein Anbieter" Fehler. Hier ist ein fix für die, die (es fühlt sich schmutzig, aber mir fehlen die Fähigkeiten, um eine bessere).
Konzeptionell, ich melde mich, als Anbieter, die jeweils dynamisch generierte Klasse erstellt, die von
roleGuard
.Also für jede Rolle aktiviert:
sollten Sie haben:
Allerdings, @AluanHaddad die Lösung ist-generieren neue Klasse für jeden Aufruf
roleGuard
, auch wennroles
parameter ist die gleiche. Mitlodash.memoize
sieht es wie folgt aus:Hinweis, jede Kombination von Rollen erzeugt eine neue Klasse, so registrieren Sie sich als Anbieter jeder Kombination von Rollen. I. e. wenn Sie haben:
canActivate: [roleGuard('foo')]
undcanActivate: [roleGuard('foo', 'bar')]
haben Sie zu registrieren:providers[roleGuard('foo'), roleGuard('foo', 'bar')]
Eine bessere Lösung wäre, sich zu registrieren Anbieter automatisch in einem globalen Anbieter-Sammlung in
roleGuard
, aber wie gesagt, mir fehlen die Fähigkeiten, um zu realisieren, dass.