web-dev-qa-db-fra.com

Routage conditionnel angulaire2

Cela pourrait être une question fondamentale, mais dans Angular2, existe-t-il un moyen de faire un routage conditionnel? Ou, quelqu'un ferait-il cela en dehors du routeur?

Je sais que le routeur ui avait une certaine capacité à le faire, mais je n'ai rien vu de semblable dans le routeur Angular2s

29
user3884414

mettre à jour

Dans le nouveau routeur, des protections peuvent être utilisées à la place https://angular.io/guide/router#milestone-5-route-guards

original (pour le routeur disparu depuis longtemps)

Implémentez le hook CanActivate lifecycle comme indiqué ici hooks de cycle de vie dans le routeur Angular2 et renvoyez false si vous souhaitez empêcher la navigation. Voir aussi https://angular.io/docs/ts/latest/api/router/CanActivate-var.html

9
Günter Zöchbauer

Comme mentionné, Angular Route Guards sont un bon moyen de mettre en œuvre des itinéraires conditionnels. Puisque le tutoriel Angular est un peu long sur le sujet, voici un bref résumé sur la façon de les utiliser avec un exemple.

1. Il existe plusieurs types de gardes. Si vous avez besoin de quelque chose de la logique if (loggedIn) {go to "/dashboard"} else { go to "/login"}, alors vous cherchez la garde CanActivate-. CanActivate peut être lu comme "Le nouvel itinéraire X peut être activé si toutes les conditions Y sont remplies". Vous pouvez également définir des effets secondaires tels que des redirections. Si cela ne correspond pas à votre logique, consultez la page du tutoriel Angular) pour voir les autres types de garde.

2. Créez un auth-guard.service.ts.

3. Remplit le auth-guard.service.ts avec le code suivant:

import { Injectable } from '@angular/core';
import {CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router';

@Injectable()
export class AuthGuardService implements CanActivate {

  constructor(
    private router: Router
  ) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const isLoggedIn = false; // ... your login logic here
    if (isLoggedIn) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }

}

4. Enregistrez auth-guard.service.ts dans votre module de routage. Ajoutez également la paire clé-valeur canActivate:[AuthGuardService] sur tous les itinéraires que vous souhaitez garder. Cela devrait ressembler un peu à ça:

const appRoutes: Routes = [
  { path: '', component: LandingComponent},
  { path: 'login', component: LoginComponent},
  { path: 'signup', component: SignUpComponent},
  { path: 'home', component: HomeComponent, canActivate: [AuthGuardService]},
  { path: 'admin', component: AdminComponent, canActivate: [AuthGuardService]},
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes)
  ],
  exports: [
    RouterModule
  ],
  providers: [
    AuthGuardService
  ]
})
export class AppRoutingModule { }

Cela devrait vous aider à démarrer.

Voici une démo minimaliste: https://stackblitz.com/edit/angular-conditional-routing

38
bersling

Au cas où vous auriez besoin de rendre un composant spécifique plutôt que de le rediriger, vous pouvez faire quelque chose comme ça:

const appRoutes: Routes = [
  {
    path: '' ,
    component: (() => {
      return SessionService.isAnonymous() ? LoginComponent : DashboardComponent;
    })()
  } 
]

J'ai utilisé cet exemple pour la page d'arrivée, où l'utilisateur qui n'était pas connecté auparavant pouvait voir la page d'arrivée ou le tableau de bord du tableau de bord.

Mise à jour Ce code fonctionnera dans un environnement dev, mais il ne se formera pas et vous obtiendrez cette erreur:

ERREUR dans Erreur lors de la compilation du modèle de 'AppRoutingModule' Les expressions de fonction ne sont pas prises en charge dans les décorateurs. Dans 'ɵ0', 'ɵ0' contient l'erreur sur src/app/app.routing-module.ts (14,25). Pensez à modifier l'expression de la fonction en une fonction exportée.

Afin de résoudre ce problème, j'ai créé un module séparé qui se présente comme suit:

import {LandingPageComponent} from '../landing-page/landing-page.component';
import {DashboardComponent} from "../dashboard/dashboard.component";
import {SessionService} from "../core/services/session.service";

const exportedComponent = SessionService.isAnonymous() ? LandingPageComponent : DashboardComponent;

export default exportedComponent;

et puis vous avez juste besoin d'importer le module fourni par cette "usine"

import LandingPageComponent from './factories/landing-factory.component';
const appRoutes: Routes = [
  {
    path: '' ,
    component: LandingPageComponent
  },
]
4
Gregory Bluvshteyn