Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
435 views
in Technique[技术] by (71.8m points)

asynchronous - Async load routes data and build route instruction for Angular 2

I try to build dynamically routes from angular2 (fetch route config from server), after that I parse it and generate instruction for component route (I have parent routes config and child into different components, because I don`t know how define route for child component into one main.app.ts file).

The problem is when app started and try to create routes config and routeGenerator is not build routes yet (async delay) cant parse routes data (because async delay, so routesData undefined now) and app is crashig. I dont know what to do with this. Looking for lifecycle hood (some like - @Angular2BeforeAppStarted ) but found nothing.

    import {Component, Input, OnChanges} from 'angular2/core';
import {RouteConfig, RouterOutlet, ROUTER_DIRECTIVES, Router} from 'angular2/router';
/* ------- !Angular 2 native components  ---------*/
import {routeGenInstance} from '../../config/routes/patient_routes';


protected const BUILT_MODULE_PATH: string = '/built/modules/patients/';

@Component({
  template: `
    <router-outlet ></router-outlet>
  `,
  directives: [RouterOutlet, ROUTER_DIRECTIVES]
})
@RouteConfig(routeGenInstance.getRouteDefinitions())

export class PatientsComponent {
  @Input();

  constructor() {}

}

Also i try to update routes in the same way (but app is crashed immediately because my Navigation link in navigation component is not have some correct link way)

import {RouteConfig, RouterOutlet, ROUTER_DIRECTIVES, Router} from 'angular2/router';

     constructor(
        private router: Router
         ) {
        router.config([
             routeGenInstance.getRoutesDefinition()
        ])
      }

my route definitions use Async loader so they are correct and work whithout async delay. I don`t know how to make angular wait for my routes definitions and thet start to run the app.

Please, help me. Thanks.

UPD:

@Thierry many thanks for your help again. You are awesome my friend and mentor. One last question (last). Can you tell me how I can define routeConfig into one app file with child subrouting definition? Its mean. I have main level routes into app files

{
  path: '/',
  name: 'Dashboard',
  component: DashboardComponent,
  useAsDefault: true
},
{
  path: '/patients/...',
  name: 'Patients',
  component: PatientsComponent
},

and patient sub routes into patientsComponent (@RouteConfig)

{
  path: '/',      // root is appRoot/patients/...
  name: 'PatientsList', component...},
  {
  "name": "Chart",
  "path": "/chart/:id", component...
},

How to define this route config only into one app.file ? (How to configure route with sub routing in one file)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

An option could be to get your configuration before bootstrapping your application.

var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]);
var http = injector.get(Http);

http.get('routes.json').map(res => res.json())
  .subscribe(data => {
    bootstrap(AppComponent, [
      HTTP_PROVIDERS
      provide('routesConfig', { useValue: data })
    ]);
  });

Then you can have access the routes configuration by dependency injection and in a synchronous way:

@Component({
  (...)
})
export class AppComponent {
  constructor(@Inject('routesConfig') private routesConfig, private router:Router) {
    // Configure here your routes
  }
}

These two questions could help you:

Edit

You can leverage the Observable.forkJoin method to load your route configuration from different requests:

var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]);
var http = injector.get(Http);

Observable.forkJoin([
  http.get('mainRoutes.json'),
  http.get('childRoutes.json')
])
.map(responses => {
  return {
    main: res[0].json(),
    children: res[1].json()
   };
 })
  .subscribe(data => {
    bootstrap(AppComponent, [
      HTTP_PROVIDERS
      provide('routesConfig', { useValue: data })
    ]);
  });

Edit1

I think that you could try something like that:

[
  {
    path: '/patients/...',
    name: 'Patients',
    component: PatientsComponent,
    childRoutes: [
      {
        path: '/',      // root is appRoot/patients/...
        name: 'PatientsList', component...
      },
      (...)
    ]
  }
]

But you need to split the content to get different elements according to the hints you want to handle:

  • one for the root:

    [
      {
        path: '/patients/...',
        name: 'Patients',
        component: PatientsComponent
      }
    ]
    
  • several for children. For example for patients:

    [
      {
        path: '/',      // root is appRoot/patients/...
        name: 'PatientsList', component...
      },
      (...)
    ]
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...