简体   繁体   中英

Angular - Router Config - redirectTo using parameters/variable segment

In the example routing configuration below, I'm receiving a Error: Cannot redirect to '/ip/:id'. Cannot find ':id' when entering localhost:8080\\sso\\ip\\1. I'm trying to understand how to redirect using variable segments of the path. In this case :id cannot seem to be found. I referenced https://vsavkin.com/angular-router-understanding-redirects-2826177761fc which describes a similar use case where a dynamic segment is used within a redirectTo property.

Does the id get resolved using the :id parameter from the initiated /sso/ip/ :id route? A similar question was asked, but never responded to: https://groups.google.com/forum/#!topic/angular/Mw0N3qYphO8 .

Any assistance is much appreciated?

const appRoutes: Routes = [
  { 
      path: 'ip',
      children: [
        {
          path: ':id',
          children: [
            {
              path: 'tcv',
              component: IpTcvComponent          
            },
            {
              path: '',
              component: IpComponent          
            }
          ]
        },
        {
          path: '',
          component: IpHomeComponent          
        }
      ]
  },  
  { 
    path: 'sso',
    children: [
      {
        path: 'ip',
        children: [
          {
            path: ':id',
            children: [
              {
                path: 'tcv',
                pathMatch: 'full',
                redirectTo: '/ip/:id/tcv'
              },
              {
                path: '',
                pathMatch: 'full',
                redirectTo: '/ip/:id'
              }
            ]
          },
          {
            path: '',
            pathMatch: 'full',
            redirectTo: '/ip'
          }
        ]
      }
    ]
  }
];

My approach would be to handle redirection manually if I can't get the routes config to work. Have a RedirectService with a redirectInFlight() method that listens to the Router.events observable. When the router tries to go to a target path such as /sso/ip/:id , transparently redirect to the right path: /ip/:id

I would then add the service to AppModule.providers , inject the service in AppComponent , and call redirectInFlight()

AppComponent

@Component({
    templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {

    //inject the RedirectService
    constructor(private redirectSvc:RedirectService){}

    //start listening to the router and redirecting
    ngOnInit() {this.redirectSvc.redirectInFlight();}
}

RedirectService

import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
import 'rxjs/Rx'; //replace with just the classes you need from RxJS library

@Injectable()
export class RedirectService {
    events$:Observable<any>; //stream of Router events

    constructor(private router:Router) {
        this.events$ =
            //listen to router events and inspect the `url` string property
            //and filter for urls that begin with /sso
            this.router.events.filter(e=> e.url && e.url.startsWith('/sso'))
    }

    redirectInFlight(){
        //First remove /sso from the start of url to fix it
        this.events$.map(e => e.url.replace('/sso',''))
            //navigate to the fixed URL
            .subscribe(newUrl=>this.router.navigateByUrl(newUrl));
    }
}

Finally, you can remove the whole sso path and its children paths from your router config, simplifying it a great deal.

Live demo

Note: This implementation is a starting point. You can make it more robust by storing and referring to a map of redirections, instead of hardcoding "/sso".

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