Abe
Abe

Reputation: 105

How do I set up routes to child components within my main component, without it loading a separate page?

I am trying to create a single-page scrolling website, in which I just click one of the header links at the top, and the page will scroll down to where that component is rather than take me to a separate page for the said component. here is what I have:

this is my home.component.html, and the only page the user should be on. below the intro section, I have an About and Experience section, where I have the tags of the respective components.

<div class="intro">
  <div class="bg"></div>
  <div class="introduction">
    <div class="intro-box">
      <span class="intro-title"> some title </span>
      <br>
      <span class="intro-subtitle">some subtitle</span>
      <p class="intro-paragraph">
        some paragraph
      </p>
    </div>
  </div>
</div>
<div class="about-section">
    <app-about></app-about>
</div>
<div class="experience-section">
    <app-experience></app-experience>
</div>

this is my header.component.html

<mat-toolbar class="toolbar" color="primary">
    <div>
      <button (click)="onToggleSidenav()" mat-icon-button>
        <mat-icon>menu</mat-icon>
      </button>
    </div>
    <div><a routerLink="/">home</a></div>
    <div>
      <ul f class="navigation-items">
        <li><a routerLink="/about">About</a></li>
        <li><a routerLink="/experience">Experience</a></li>
    
      </ul>
    </div>
  </mat-toolbar>

and finally here is my routing.module.ts. I had individual routes for each component before, but that loaded a separate page for each one. so my logic was since the about and experience component are within the home component, I would just need to make them children of the home route. it seems to work as the URL changes when I click the links, and it remains on the home page, but I expected it to move down the page to where that component is once I click the link.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AboutComponent } from './about/about.component';
import { ExperienceComponent } from './experience/experience.component';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
       {
        path: 'about',
        component: AboutComponent,
      },
      { path: 'experience', component: ExperienceComponent },
     ],
  },

];

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

Upvotes: 0

Views: 1096

Answers (1)

Fabian Strathaus
Fabian Strathaus

Reputation: 3570

Explanation why your approach does not work: Unfortunately that is not what the angular router is for. Angular Router renders the component for the matching path right after a router-outlet tag. If you configure child routes, angular tries to find a nested router-outlet tag to render the component. Since this router-outlet is not found nothing has to be rendered. This is the reason the URL changes, but nothing else happens.

Solution: Usually the best option to change scroll-position after a link click is to assign an ID to the tag you want to target (in this case to your "about-section" and your "experience-section"). Afterwards you can navigate to this id by setting <a href="#your-id">. You don't need any child routes in angular in order to do this.

...
<li><a href="#about-section">About</a></li>
<li><a href="#experience-section">Experience</a></li>
...

Pro-tip: In order to have a more user-friendly scrolling experience you should probably set scroll-behavior: smooth to your scroll-container.

Upvotes: 2

Related Questions