web-dev-qa-db-fra.com

Les itinéraires enfants du sous-module ne fonctionnent pas ("Erreur: impossible de faire correspondre les itinéraires.")

J'utilise Angular 6.0.3. J'ai un sous-module appelé "Admin" avec trois composants. L'itinéraire de la composante racine de l'administrateur ("AdminComponent") fonctionne correctement (path: ""), mais je ne semble pas pouvoir en déclencher d'autres. Pourquoi Angular ne trouve-t-il pas mes itinéraires?

routes.ts

import { Routes } from "@angular/router";
import { SplashComponent } from "./splash/splash.component";
import { LoginComponent } from "./login/login.component";
import { WatchComponent } from "./watch/watch.component";

import { AdminComponent } from "./admin/admin/admin.component";
import { HomeComponent as AdminHomeComponent } from "./admin/home/home.component";
import { AddSongComponent } from "./admin/add-song/add-song.component";
import { AdminGuard } from "./auth/admin.guard";

export const appRoutes: Routes = [
  {
    path: "",
    children: [
      { path: "", component: SplashComponent, pathMatch: "full" },
      { path: "login", component: LoginComponent, pathMatch: "full" },
      { path: "watch", component: WatchComponent, pathMatch: "full" },
      {
        path: "admin",
        component: AdminComponent,
        pathMatch: "full",
        canActivate: [AdminGuard],
        children: [
          {
            path: "",
            component: AdminHomeComponent,
            pathMatch: "full",
            outlet: "admin"
          },
          {
            path: "add-song",
            component: AddSongComponent,
            pathMatch: "full",
            outlet: "admin"
          }
        ]
      }
    ]
  }
];

admin/admin/admin.component.html

<router-outlet name='admin'></router-outlet>

admin/home/home.component.html

<div>

   <a mat-raised-button [routerLink]="['add-song']">Add new song</a>

</div>

remarque: j'ai aussi essayé [routerLink]="[{ outlets: { admin: ['add-song'] } }], mais la route n'a toujours pas été trouvée.

4
zakdances

Je vous recommande de regarder la fonctionnalité Lazy-loading lors du chargement de sous-modules, ce qui est la méthode correcte pour charger lorsque vous avez plusieurs modules.

Dans votre cas, vous avez le module admin en tant que sous-module, voici donc la configuration du routage,

 RouterModule.forRoot([
      { path: '', redirectTo: 'splash', pathMatch: 'full' },
      { path: 'splash', component: SplashComponent },
      { path: 'admin', loadChildren: './admin/admin.module#AdminModule' },
      { path: '**', component: NotFoundComponent }
    ], { enableTracing: true })]

et le routage Admin.module est le suivant,

RouterModule.forChild([
      {
        path: '', component: AdminComponent,
        children: [

          { path: '', component: AdminHomeComponent }
          ,
          { path: 'add-song', component:  AddSongComponent}]
      }
  ])
  ]

FONCTIONNEMENT DE STACKBLITZ DEMO

ROUTES: 

Éclaboussure

Admin

Admin-AddSong

10
Sajeetharan

Cela pourrait être une réponse tardive, mais je voudrais me concentrer sur une chose importante, le compilateur angulaire est très intelligent, il détecte la racine sur laquelle vous êtes actuellement. Ainsi, si vous appelez une route imbriquée à partir d'un modèle .html, elle vérifiera automatiquement votre route actuelle. dans l'url et quelle que soit la route que vous voulez, ceci sera simplement ajouté à la route actuelle.

En termes simples, ce que vous essayez de faire dans votre code à partir de admin/home/home.component.html, vous essayez de déclencher la route add-song et vous obtiendrez un résultat, étant donné que admin/add-song n’existe pas.

itinéraires de partage config. pour les enfants et un autre extrait de code.

children: [
      {
        path: "admin-home",
        component: AdminHomeComponent,
        pathMatch: "full",
        outlet: "admin"
      },
      {
        path: "add-song", 
        component: AddSongComponent, 
        pathMatch: "full",
        outlet: "admin"
      },
      {path: '', 
      redirectTo:'admin-home', 
      pathMatch: 'full'}
    ]

maintenant de votre admin/home/home.component.html utiliser ci-dessous routerLink

  <div>
    <a mat-raised-button [routerLink]="['/add-song']">Add new song</a>
  </div>

Jusqu’à présent, vous essayiez d’ajouter un chemin relatif. Dans Angular, spécialement dans routerLink, il détectera le chemin actuel et ajoutera le chemin attendu à la fin de votre chemin actuel. Il vous donnera alors une erreur. Essayez donc de fournir un chemin absolu dans votre itinéraires.

Mais cette méthode.router.navigate () ne comprendra pas automatiquement sa route actuelle.Elle commence toujours la route à partir de root route.ie si vous essayez d’appeler un chemin imbriqué à partir d’un fichier .ts, angular ne reconnaîtra pas le chemin actuel. vous êtes prêt à dire à Angular ce qui est la route actuelle, puis à partir du fichier .ts, vous pouvez faire quelque chose comme ceci

import { ActivatedRoute, Router } from '@angular/router';
...
constructor(private route: ActivatedRoute, private router: Router) { }
...
this.router.navigate(['./add-song'], {relativeTo: this.route}); 

Encore une chose, c'est comme <a mat-raised-button [routerLink]="['add-song']">Add new song</a> c'est pareil que <a mat-raised-button [routerLink]="['./add-song']">Add new song</a> ou <a mat-raised-button [routerLink]="['../add-song']">Add new song</a> c'est un chemin relatif, vous devez utiliser un chemin absolu

Sinon, essayez d'appeler votre route à partir du composant .ts sans la propriété relativeTo et le chemin relatif.

J'espère que cela peut fonctionner pour vous

1
Prasanna Sasne

Le problème est que vous ne définissez aucun composant pour path ""

import { Routes } from "@angular/router";
import { SplashComponent } from "./splash/splash.component";
import { LoginComponent } from "./login/login.component";
import { WatchComponent } from "./watch/watch.component";

import { AdminComponent } from "./admin/admin/admin.component";
import { HomeComponent as AdminHomeComponent } from "./admin/home/home.component";
import { AddSongComponent } from "./admin/add-song/add-song.component";
import { AdminGuard } from "./auth/admin.guard";

export const appRoutes: Routes = [
  {
    path: "",
    component: SplashComponent,
    children: [
      { path: "login", component: LoginComponent, pathMatch: "full" },
      { path: "watch", component: WatchComponent, pathMatch: "full" },
      {
        path: "admin",
        component: AdminComponent,
        pathMatch: "full",
        canActivate: [AdminGuard],
        children: [
          {
            path: "",
            component: AdminHomeComponent,
            pathMatch: "full",
            outlet: "admin"
          },
          {
            path: "add-song",
            component: AddSongComponent,
            pathMatch: "full",
            outlet: "admin"
          }
        ]
      }
    ]
  }
];
1
Debojyoti

Avez-vous essayé de créer des composants liés à l’administrateur dans son propre module? Vous pouvez ensuite créer un admin-routing.module.ts

const adminRoutes: Routes = [
  {
    path: '',
    component: AdminComponent,
    children: [
      {
        path: '',
        children: [
          { path: 'add-song', component: AddSongComponent },
          { path: 'something-else', component: SomeOtherComponent },
          { path: '', component: AdminDefaultComponent }
        ]
      }
    ]
  }
];

@NgModule({
  imports: [ 
    RouterModule.forChild(adminRoutes)
  ],
  exports: [
    RouterModule
  ]
})
export class AdminRoutingModule {}

Ensuite, dans votre app-routing.module principal, vous pouvez vous y référer en tant que

const appRoutes: Routes = [
  { path: '', component: SplashComponent },
  { path: 'login', component: LoginComponent },
  {
    path: 'admin',
    loadChildren: 'app/admin/admin.module#AdminModule',
  },
  { path: '**', component: SomeOtherComponent }
];

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

edit : J'ai remarqué que vous avez créé son propre sous-module, vous devrez donc créer un module de routage pour ce sous-module.

1
DavidZ

Voici un exemple de travail de votre code , le correctif supprimait simplement pathMatch: 'full' partout sauf pour la route de redirection.

Une route de redirection nécessite une propriété pathMatch pour indiquer au routeur comment faire correspondre une URL au chemin d'une route. Le routeur génère une erreur si vous ne le faites pas. Dans cette application, le routeur doit sélectionner la route vers le composant HeroListComponent uniquement lorsque l'adresse URL complète correspond à "", définissez donc la valeur pathMatch sur "full".

Considérons les docs, pour en savoir plus sur la propriété.

0
chiril.sarajiu

Je pense que votre problème est lié au chemin qui est générant angulaire pour la balise d'ancrage. vous faites actuellement référence à un chemin "add-song". Angular considère ce chemin comme "localhost: 4200/add-song". Si vous voulez le router vers admin/add-song, vous devez définir le chemin complet (vous ne savez pas pourquoi angular le faire) Si tu pouvais essayer 

 <a mat-raised-button [routerLink]="['admin/add-song']">Add new song</a>

Cela peut fonctionner pour le moment mais ce ne serait pas une solution parfaite . Merci

0
Ali Khan