Dynamic routing based on external data

2020-01-25 09:38发布

问题:

I'm working on an application that needs to configure routes based on some external data source. The life cycle of the app looks like this:

  • ng2 inits with App
  • App contains Header, router-outlet, and Footer
  • default route is configured to homeComponent
  • homeComponent has categoriesListComponent
  • categoriesListComponent calls a get method from categoriesService
  • categoriesService gets back a list of categories from the api
  • categoriesComponent renders the list and injects new routes for each category back into App via a routesConfigurator

There's actually another layer of abstraction with a routesService but that isn't needed for this example

That part works, since we started at the home page, the API call was made and created the routerConfigs for each category. So when the user clicks on a category, the route is already configured with the correct categoryComponent + metadata and they're shown the correct information.

However, if a specific category page is accessed directly ng2 doesn't have the routerConfig for that route yet, since the API call hasn't returned anything, let alone fired off yet. Ng2 just renders the basic App with Header, Footer and an empty router-outlet.

The only solution I can think of is pretty "hacky". Keep a cached json file on the app server and load it up in the initial html, then inject that into a service at ng2 bootstrap/init. That way the routes are configured before ng2 even beings to render the page.

I'm asking for any other possible suggestions, perhaps someone with a bit more ng2 experience that me can chime in. Maybe this was solved already and I just haven't perfected my google-fu enough.

Thanks in advance.

回答1:

In the new router (>= RC.3) https://angular.io/docs/ts/latest/api/router/index/Router-class.html#!#resetConfig-anchor resetConfig can be used to load new routes

router.resetConfig([
 { path: 'team/:id', component: TeamCmp, children: [
   { path: 'simple', component: SimpleCmp },
   { path: 'user/:name', component: UserCmp }
 ] }
]);

You would have a custom routerLink directive or just some link or button that calls an event handler on click where new routes are loaded and then router.navigate(...) is called to navigate to the appropriate route.

https://github.com/angular/angular/issues/11437#issuecomment-245995186 provides an RC.6 Plunker



回答2:

I don't know if one of the above comments is your solution of the result that you wanted but I have a new method that might be interested in you and other developers out there.

I created a javascript file where I add my routes.

"use strict";
const home_component_1 = require("location javascript component file");
exports.DYNAMIC_ROUTES = [
    { path: '', component: your_component_name_component_1.YourComponentName },
]

Then in the app.routing.ts (your routing file), you will have to add an import statement to your javascript file

// JAVASCRIPT IMPORT
import { DYNAMIC_ROUTES } from 'location javascript file';

const appRoutes: Routes = [
    { path: 'home', component: NormalLayoutComponent, children: DYNAMIC_ROUTES },
]

Hereby by doing this method you now can manipulate the javascript file with Typescript for dynamic changes. You can even create the file by php and then keep it in the same place. Notice you need to have an already compiled component in my case there is one and it handles all the routes in one component for me.

Also, make sure if you are using a compiler that removes your javascript make sure to read them to the build folder or make sure it compiles with your application.