简体   繁体   中英

Angular 2 Routing Not Finding Routes

I am having trouble understanding my current issue where I am not able to load the new page when the routerlink is clicked.

I have tried many different structures for the link but no matter what I change it to the error in the console says

VM39436:48 EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'stream'

I am using to template layouts then making my pages children of those layouts. One layout is secure and one layout is public.

In app.routing.ts

const APP_ROUTES: Routes = [
      {
        path: '',
        redirectTo: 'stream',
        pathMatch: 'full',
    },
    {
        path: 'profile',
        component: SecureLayoutComponent,
        data: {
            title: 'Secure Views'
        },
        children: [
            {
                path: 'Profile',
                loadChildren: 'profile/profile.module#ProfileModule'
            }
        ]
    },
    {
        path: '',
        component: PublicLayoutComponent,
        data: {
            title: 'Public Views'
        },
        children: [
            {
                path: 'stream',
                loadChildren: 'stream/stream.module#StreamModule',
            }
        ]
    }
];

Now I have a folder for profile and a folder for stream.

so when you move to stream directory this is the stream-routing.module.ts

import { NgModule }             from '@angular/core';
import { Routes,
         RouterModule }         from '@angular/router';

import { StreamComponent }   from './stream.component';

const routes: Routes = [
    {
        path: '',
        component: StreamComponent,
        data: {
            title: 'Stream'
        }
    }
];

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

And this is the profile-routing.module.ts

import { NgModule }             from '@angular/core';
import { Routes,
         RouterModule }         from '@angular/router';

import { ProfileComponent }   from './profile.component';

export const routes: Routes = [
    {
        path: '',
        data: {
            title: 'Secure Pages'
        },
        children: [
            {
                path: 'profile',
                component: ProfileComponent,
                data: {
                    title: 'Profile Page'
                }
            }
        ]
    }
];

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

So this loads fine when the app renders. But when I try to click,

  <a class="nav-link"  routerLinkActive="active" [routerLink]="['../profile/profile']">Profile</a>

Or

  <a class="nav-link"  routerLinkActive="active" [routerLink]="['../profile']">Profile</a>

or

  <a class="nav-link"  routerLinkActive="active" [routerLink]="['/profile']">Profile</a>

I get the error mentioned above,

So from the / directory

/app.routing.ts

/stream/stream.component.ts & stream-routing.module.ts

/profile/profile.component.ts & profile-routing.module.ts // Can't access this from public layout.

I think you just need to remove the redirect route

  {
    path: '',
    redirectTo: 'stream',
    pathMatch: 'full',
  },

like

const APP_ROUTES: Routes = [
    {
        path: 'profile',
        component: SecureLayoutComponent,
        data: {
            title: 'Secure Views'
        },
        children: [
            {
                path: 'Profile',
                loadChildren: 'profile/profile.module#ProfileModule'
            }
        ]
    },
    {
        path: '',
        component: PublicLayoutComponent,
        data: {
            title: 'Public Views'
        },
        children: [
            {
                path: 'stream',
                loadChildren: 'stream/stream.module#StreamModule',
            }
        ]
    }
];

I am adding this answer to help anyone else who is having problems with multi level routing, child routes, or auth guard.

I use two template in my apps,

/templates/public.component.ts
/templates/secure.component.ts

Here is the secure-layout.component.ts file

import { Component, OnInit }        from '@angular/core';
import { Router }                   from '@angular/router';
import { Auth }                     from './../services/auth.service';

@Component({
    providers: [ Auth ],
    selector: 'app-dashboard',
    templateUrl: './secure-layout.component.html'
})
export class SecureLayoutComponent implements OnInit {

    constructor( private router: Router, private auth: Auth ) { }

    ngOnInit(): void { }
}

Here is the public-layout.component.ts file

import { Component, OnInit }    from '@angular/core';
import { Router }               from '@angular/router';
import { Auth }                 from './../services/auth.service';

@Component({
    providers: [ Auth ],
    selector: 'app-dashboard',
    templateUrl: './public-layout.component.html'
})
export class PublicLayoutComponent implements OnInit {

    constructor( private router: Router, private auth: Auth ) { }

    ngOnInit(): void { }
}

This way I can add guard to the secure template redirecting any unauthorized traffic back to the public template. So from the /app.routing.ts file I creates routes for the layouts then inside of the components I create I create child routes which become child routes to the respective template.

app.routing.ts

import { Routes, RouterModule }     from "@angular/router";

import {Guard}                      from "./services/guard.service";

//Layouts
import { PublicLayoutComponent }    from './layouts/public-layout.component';
import { SecureLayoutComponent }    from './layouts/secure-layout.component';

import { STREAM_ROUTES }            from "./stream/stream.routes";
import { PROFILE_ROUTES }           from "./profile/profile.routes";

const APP_ROUTES: Routes = [
    { path: '', redirectTo: '/stream', pathMatch: 'full', },
    { path: '', component: PublicLayoutComponent, data: { title: 'Public Views' }, children: STREAM_ROUTES },
    { path: '', component: SecureLayoutComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: PROFILE_ROUTES }
];



export const routing = RouterModule.forRoot(APP_ROUTES);

/stream/stream.routes.ts

import { Component, OnInit } from '@angular/core';

@Component({
  templateUrl: './stream.component.html',
})

export class StreamComponent {

  constructor() { }

}

/profile/profile.routes.ts

import { Routes } from "@angular/router";

import { ProfileComponent }   from './profile.component';

export const PROFILE_ROUTES: Routes = [
    { path: '', redirectTo: 'profile', pathMatch: 'full' },
    { path: 'profile', component: ProfileComponent }
];

In this example stream is where I keep my public views and profile is where all of my secure views will be. So if I wanted to create a new public view I would go into stream and create a new route then create the html file as well as component.ts file.

I hope this is helpful. I think this is a very nice way to handle routing for any app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM