2016-04-05 58 views
7

Cerco di creare percorsi dinamici da angular2 (recupera route config dal server), dopo di che lo analizzo e genera istruzioni per il route del componente (ho padre route config e child in componenti diversi, perché non so come definire il percorso per il componente figlio in un file main.app.ts).Async load routes data and build route instruction for Angular 2

Il problema è quando l'app è stata avviata e provare a creare percorsi config e routeGenerator non è ancora percorso di costruzione (ritardo asincrono) può t parse routes data (because async delay, so routesData undefined now) and app is crashig. I don t sapere cosa fare con questo. Alla ricerca del ciclo di vita (alcuni come - @ Angular2BeforeAppStarted) ma non hanno trovato nulla.

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() {} 

} 

Inoltre provo ad aggiornare percorsi nello stesso modo (ma app è schiantato subito perché il mio link di navigazione nella componente di navigazione non è avere un modo link corretto)

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

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

mie definizioni uso Come Async caricatore in modo che siano corretti e funzionano senza ritardo asincrono. Non so come rendere angolare l'attesa per le definizioni dei miei percorsi e avviare l'app.

Per favore, aiutatemi. Grazie.

UPD:

@Thierry molte grazie per il vostro aiuto di nuovo. Sei fantastico amico mio e mentore. Un'ultima domanda (ultima). Puoi dirmi come posso definire routeConfig in un file app con definizione di sottotitolazione figlio? La sua media. Ho principali vie di livello in file app

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

e percorsi sub paziente nella patientsComponent (@RouteConfig)

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

Come definire questo percorso di configurazione solo in uno app.file? (Come configurare l'instradamento con il sottotitolo in un file)?

+0

'RouterOutlet' è già contenuto in' ROUTER_DIRECTIVES', non è necessario aggiungerlo di nuovo. –

+0

Come appare 'routeGenInstance.getRouteDefinitions()'? Cosa restituisce? –

risposta

6

Un'opzione potrebbe essere quella di ottenere la configurazione prima di avviare l'applicazione.

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 }) 
    ]); 
    }); 

Quindi è possibile avere accesso alla configurazione percorsi per l'iniezione di dipendenza e in modo sincrono:

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

Queste due domande potrebbero aiutare:

Modifica

è possibile sfruttare l'osservabile.forkJoin metodo per caricare la configurazione di percorso da diverse richieste:

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

Penso che si potrebbe provare qualcosa di simile:

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

ma è necessario dividere il contenuto ottenere elementi diversi in base ai suggerimenti che si desidera gestire:

  • uno per la radice:

    [ 
        { 
        path: '/patients/...', 
        name: 'Patients', 
        component: PatientsComponent 
        } 
    ] 
    
  • diversi per i bambini. Ad esempio per i pazienti:

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

Thierry, grazie per la risposta, ci proverò ora. Ma ho ancora una domanda su questo.In questo momento tengo la configurazione dei miei percorsi in 2 file e la includo in 2 componenti diversi (uno - Percorso principale per app.main, percorso secondario - secondario, per paziente (ad esempio)). È possibile unirsi alla sua route config e riavviarla solo nel file app.ts? – Velidan

+0

Prego! Sì, puoi sfruttare il metodo Observable.forkJoin per questo ... Ho aggiornato la mia risposta (l'iniezione rimane la stessa). –

+0

Mille grazie a voi Thierry. Quindi, quando ricevo questi dati e li fornisco nell'app principale, dovrei usare il router.config nel costruttore dell'app invece del decoratore @RouteConfig? perché non so come ottenere config da Injector per @RouteConfig. Siamo spiacenti, per favore, per domande fittizie. – Velidan

4

Nel nuovo router (>= RC.3) https://angular.io/docs/js/latest/api/router/index/Router-class.html#!#resetConfig-anchorresetConfig può essere utilizzato

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

Vedi anche https://github.com/angular/angular/issues/9472#issuecomment-229230093

  • È possibile caricare i componenti in modo asincrono, fornendo uno SystemJsComponentResolver.
  • Al momento, è possibile caricare i percorsi in modo asincrono e imperativamente aggiornare la configurazione utilizzando resetConfig.
  • Una volta che gli AppModules sono in master, utilizzeremo quelli per implementare il caricamento asincrono dei subconfig.

https://github.com/angular/angular/issues/11437#issuecomment-245995186 fornisce un rc.6 Plunker

0

Utilizzando osservabili/promette di fornire traduzioni di percorso non è una soluzione affidabile, da cui il router angolare aspetta route [] o delle vie, ma una richiesta HTTP può solo restituire un Osservabile/Promessa.

L'app Angolare viene inizializzata, ma il processo di recupero delle traduzioni di percorso continua ancora utilizzando Observables/Promises.

Come ha detto Thierry Templier, per ottenere la configurazione prima di avviare l'applicazione si risolverebbe il problema.

Inoltre, controllare lo @ngx-i18n-router/core su github.