2

Maybe anyone know how to dynamicly build routes (or just dynamic import Components).

For example:

I have JSON that contains objects with RouteName, path, ComponentNames (string). I want to iterate it and build dynamicly routes definitions (route config). But I don`t know, how to make dynamic Component import. I can passs string "ComponentName" from JSON to import rule, because import want static definition (finded it on some soure from googling).

failed

let a = "MyComponentName"
import {a} from ......     

(One idea that I came up with - its like create some map key-value, and keep into key - route, value - Component, and after that equals routename from JSON and my MAP and push needed component into final route config array. But its so ugly solution) Maybe another way exists?

I stuck. Many thanks for any help.....

Velidan
  • 5,526
  • 10
  • 48
  • 86

3 Answers3

2

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

update

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

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

original

What should work is

import from 'myComponents' as myComponents;

...

someFunc(name:string) {
  console.debug(myComponents[name]);
}

Routes can be loaded using

constructor(private router:Router) { }

someFunc() {
  this.router.config([
    { 'path': '/', 'component': IndexComp },
    { 'path': '/user/:id', 'component': UserComp },
  ]);
}

I haven't tried this myself.

See also this related question Angular2 App Routing through Services

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
2

You could leverage Async routes to do this. Based on your route configuration, you could load route from modules. In this case, you need to add the module path to get the components to associate with routes.

Here is a sample:

var routes = {
  path: '/path',
  name: 'some name',
  module: './my.component',
  component: 'MyComponentName'
}
routes.forEach((route : any) => {
  this.routeConfigArray.push(
      new AsyncRoute({
          path : route.path,
          loader : () => System.import(route.module).then(m => m[route.component]),
          name : route.name
      });
  );
});

this._router.config(this.routeConfigArray);

Another approach could be to add a function to get the name of functions. Based on this you can check if you have a potential component that matches.

Here is a sample:

ngOnInit() {
  this.routes = [
    {
      path: '/test', component: 'OtherComponent', name: 'Test'
    }
  ];
  this.configureRoutes(this.routes);
  this.router.config( this.routes);
}

configureRoutes(routes) {
  var potentialComponents = [ OtherComponent ];
  routes.forEach((route) => {
    route.component = potentialComponents.find((component) => {
      return component.name === route.component;
    });
  });
}

See this plunkr: https://plnkr.co/edit/KKVagp?p=preview.

See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Whenever I try to add more than one route, I cannot get it to work. this.routes = [ { path: '/test', component: 'OtherComponent', name: 'Test' }, { path: '/test2', component: 'OtherComponent2', name: 'Test2' } ]; – crh225 Aug 04 '16 at 13:27
1

say. three screens as page1, page2 and page3 and components as app/page1.ts, app/page2.ts and app/page3.ts

       let screens : Array<string> = ["Page1","Page2","Page3"];
       let aRouter : RouteDefinition;
       this.routes = new Array<RouteDefinition>();
       screens.map(function(screenId){
           aRouter = new AsyncRoute({
                path: "/" + screenId,
                name: screenId,
                loader: () =>  System.import("app/" + screenId).then(c => c[screenId]) // not  import {page1, page2, page3}}
            });
            this.routes.push(aRouter);
       }.bind(this));  //we need to bind to current "this" instead of global this
        this.router.config(this.routes);

trick is .bind(this), which is vanella javscript for whole sulution, check this Dynamically load Angular 2 Async router https://github.com/Longfld/DynamicalAsyncRouter

Long Field
  • 858
  • 9
  • 16