web-dev-qa-db-fra.com

Dans Angular, comment naviguer directement vers un chemin à l'intérieur d'un module chargé paresseusement?

Je voudrais avoir deux chemins de niveau supérieur pour se connecter et s'inscrire.

Je préférerais ne pas avoir à faire auth/log-in et auth/register.

Cependant, les composants auth sont dans un module séparé, ce qui est bien car il ne doit pas être chargé sauf demande spécifique.

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

Comment puis-je spécifier lors de la définition de mes itinéraires que je souhaite log-in chemin d'accès au log-in chemin à l'intérieur le module AuthModule chargé paresseux, et le chemin register pour accéder au chemin registerà l'intérieur le module chargé paresseux?

14
CodyBugstein
export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

Je vais essayer de dire que ce n'est pas possible . Lazy loading modules chargés par des redirections. Ça signifie:

  • Commencez à naviguer log-in.
  • Le module de chargement paresseux commence à se charger
  • Après un chargement réussi, l'URL sera somePath/log-in
  • Alors, quelle est la prochaine? Ici, le processus de redirection est démarré. Donc, le fichier routing.ts de chaque module de chargement paresseux devrait contenir le chemin du point d'entrée comme:

    {
       path: '',
       redirectTo: 'somePath/ChildPath' // or component: SomeComponent
    }
    

Peu importe la route qu'il a parcourue, s'il s'agit d'un module paresseux, il essaiera de trouver le chemin d'entrée. Dans votre cas, deux routes chargeant le même module, mais elles font également référence au même chemin de route d'entrée (path: '').

Si vous voulez vraiment les diviser, ils doivent être alloués dans différents modules.

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/someModule#someModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

some-module.routing.ts:

{
    path: '',
    component: LoginComponent,

},

MISE À JOUR 29.04.18. Solution simple avec un composant de plus

La solution consiste à créer un composant supplémentaire qui agit comme moteur de rendu d'autres composants en fonction du url actuel.

app-routing.module:

const appRoutes: Routes = [
 ...

  {
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',

  },
  {
    path: 'login',
    loadChildren: 'app/admin/admin.module#AdminModule',

  },
  {
    path: 'crisis-center',
    loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule',
    // data: { preload: true }
  },
  { path: '', redirectTo: '/superheroes', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

Dans admin.module créer composant de rendu

central.component.ts:

...

@Component({
  selector: 'app-central',
  templateUrl: './central.component.html',
  styleUrls: ['./central.component.css']
})
export class CentralComponent implements OnInit {

  currentComponent: LoginComponent | AdminComponent;

  constructor(public router: Router, public activatedRoute: ActivatedRoute) { }

  ngOnInit() {
    if (this.router.url === '/login') {
      this.currentComponent = LoginComponent;
    } else {
      this.currentComponent = AdminComponent;
    }
  }
}

central.component.template:

<ng-container *ngComponentOutlet="currentComponent"></ng-container>

Ainsi, comme vous pouvez le voir, le composant central rendra le composant dynamiquement en fonction du chemin de l'url.

Pour le rendu utilisé méthode d'approche déclarative avec NgComponentOutlet

Plus de détails sur l'approche impérative et déclarative: https://stackoverflow.com/a/49840700/5677886

Démo StackBlitz

6
Yerkon

Jusqu'à présent, il n'est pas possible de configurer les itinéraires comme vous le vouliez dans votre message. Vous pouvez le voir si vous activez la journalisation pour votre routeur. Le chemin de votre module (connexion, enregistrement) est utilisé et dans le routage de votre module, il ne vous restera plus que '', Qui ne peut pas être associé à deux composants différents.

Vous pouvez néanmoins y parvenir, même si ce n'est pas si joli et je ne sais pas comment/si cela fonctionne dans les anciens navigateurs.

Dans votre app.module.ts

const APP_ROUTES: Routes = [
    { path: 'login', redirectTo: 'auth/login', pathMatch: 'full' },
    { path: 'register', redirectTo: 'auth/register', pathMatch: 'full' },
    { path: 'auth', loadChildren: 'app/auth/auth.module#AuthModule', pathMatch: 'prefix'},
];

@NgModule( {
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        RouterModule,
        RouterModule.forRoot(APP_ROUTES)
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

et le auth.module.ts ressemble à ceci

const ROUTES: Routes = [
    { path: 'login', component: LoginComponent, pathMatch: 'full' },
    { path: 'register', component: RegisterComponent, pathMatch: 'full' }
];

@NgModule( {
    imports: [
        CommonModule,
        RouterModule.forChild( ROUTES )
    ],
    declarations: [
        LoginComponent,
        RegisterComponent
    ]   
} )
export class AuthModule { }

Vous pouvez ensuite accéder aux itinéraires par <a routerLink="login">Login</a>, Fonctionne également avec router.navigate. Malheureusement, cela vous laissera avec auth/login Ou auth/register Dans l'url de votre navigateur même si le client appelle juste /login.

Vous pouvez résoudre ce problème en créant une entrée dans votre window.history - comme je l'ai dit pour ne pas être joli et cela doit être fait dans votre constructeur de composants. window.history.pushState('register', 'Register', 'register'); ou window.history.pushState('login', 'Login', 'login'); dans les composants laissera l'url de votre navigateur avec /login et /register.

Le meilleur moyen serait d'étendre le routeur angular avec cette fonctionnalité et de l'utiliser comme routeur personnalisé, mais vous devrez vraiment vous y lancer pour cela et avec la prochaine mise à jour, vous pourriez se faire défoncer.

Peut-être que cela vous aide

Meilleures salutations

7
Fussel

Le module de routage d'application peut préfixer (ou non) les itinéraires d'un module d'entités. Si vous ne voulez pas de préfixe d'itinéraire comme /auth, soit en utilisant le chargement différé ou non), vous pouvez faire quelque chose comme ceci:

app-routing.module.ts:

  {
    path:             '',
    canActivate:      [AuthGuard],
    canActivateChild: [AuthGuard],
    children:         [
      {
        path:      '',
        component: HomeComponent,
      },
      {
        path:         '',
        loadChildren: 'app/auth/auth.module#AuthModule',
      },
      {
        path:      'settings',
        component: SettingsComponent,
      },
    ],
  },

Le top-route du module paresseux n'a même pas besoin d'être statique, vous pouvez avoir une configuration comme:

auth-routing.module.ts:

const routes: Routes = [
  {
    path:      ':pageName',
    component: AuthComponent,
    resolve:   {
      pageInfo: AuthResolver,
    },
    children:  [
      {
        path:      'login',
        component: LoginComponent,
      },
      {
        path:      'register',
        component: RegisterComponent,
      },
    ],
  },
];
1
Mike Drakoulelis