ng-routing

Angular Routing


Motivation

@switch (state) {
  @case (login) {
    <app-login></app-login>
  }
  @case (shop) {
    <app-shop></app-shop>
  }
  @case (product-details) {
    <app-details [product]='product'></app-details>
  }
  @case (user-details) {
    <app-user [user]='user'></app-user>
  }
  @case (admin) {
    @if (isAdmin(user)) { <app-admin></app-admin> }
  }
  @default {
    <app-not-found></app-not-found>
  • 😕
  • Back-Button ⚠️

Setup

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes, withComponentInputBinding()),]
};
const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'shop', component: ShopComponent }
];
<a routerLink='/login'>Login</a>
<a routerLink='/shop'>Shop</a>
<a routerLink='/search' 
   [queryParams]='{ q: "angular"}'> 
   Search</a> <!-- /search?q=angular -->

<!-- The routed views render in the <router-outlet>-->
<router-outlet></router-outlet>

Active link styling

<a 
  routerLink='/login' 
  routerLinkActive='active'>
  Login
</a>
<a routerLink='/shop' ... >Shop</a>

css-Klasse active, falls aktuelle Route /login


Routing mit input

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'shop', component: ShopComponent },
  { path: 'products/:id', component: ProductComponent }
];
export class ProductComponent implements OnInit{
  id = input.required<number>();
  
  constructor() {
      // input not yet available
  }
  
  ngOnInit() {
      console.log(this.id());
  }
}

Wildcard Routes

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'shop', component: ShopComponent },
  { path: 'products/:id', component: ProductComponent },
  { path: '**', component: PageNotFoundComponent }
];
  • paths werden nach Reihenfolge versucht
  • ⚠️ muss letzte sein ⚠️

Redirects

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'shop', component: ShopComponent },
  { path: 'products/:id', component: ProductComponent },
  { path: '',   redirectTo: '/login', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

auch als Funktion möglich

{
  path: 'logout', 
  redirectTo: ({ queryParams }) =>  {
    if (condition)
      return '/login';
    else
      return '/shop';
  }
}

Routing aus ts

export class ShopComponent {
  
  router = inject(Router);
  route = inject(ActivatedRoute);
  
  navigate() {
    // /products/angular/42
    this.router.navigate(['/products','angular',42]);
    
    // /products/42
    this.router.navigate(['/products', { id: 42 }]);
    
    // /search?q=angular
    this.router.navigate(['/search', 
        { queryParams: { q: 'angular' } }]);
    
    // /shop/basket
    this.router.navigate(['basket'], { relativeTo: this.route });
  }
}

Route Guards

{
  path: 'admin', 
  component: AdminComponent, 
  canActivate: [authGuard]
}
export const authGuard: CanActivateFn = (
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => {
    const authService = inject(AuthService); 
    const router = inject(Router);

    if (authService.isLoggedIn()) {
        return true;
    } else {
        router.navigate(['/login']);
        return false;
    }
}

canDeactivate äquivalent