2016-10-26 5 views
2

Ich verwende Angular 2.1 für eine große Anwendung, die mehrere Submodule hat, die jeweils Sub-Anwendungen nach Feature definieren. Das Modul der obersten Ebene konfiguriert das RouterModul mit allen untergeordneten Routen für die gesamte Anwendung, indem es die Routen jeder untergeordneten Anwendung usw. importiert. Aus der Perspektive der Unteranwendung leitet es also relativ zu der Anwendung, für die die Anwendung der höchsten Ebene die Route festlegt Die Unteranwendung weiß nicht direkt, was ihre oberste Route tatsächlich ist.Angular2-Routing zwischen Unteranwendungen in Modulen

Einige dieser Unteranwendungen verfügen über Zusammenfassungsbereiche für Einheiten, die in einer anderen Unteranwendung vollständiger definiert/gesteuert werden. Konzeptionell sind die Module Setup wie folgt aus:

Module 1: 
    Imports Module 2 
    Routes for Module 1 
    Component1A 
    App1View (contains Component1A, M2SummaryComponent) 

Module 2: 
    Routes for Module 2 (one exported as APP2_VIEW_ROUTE, type Route) 
    Component2A 
    Component2B 
    M2SummaryComponent 
    App2View (contains Component2A, Component2B) 
    ...etc. 

Ich bin für ein Design-Muster suchen, wobei die M2SummaryComponent geschrieben werden kann, um eine Strecke innerhalb des eigenen Modul zu verbinden, während es in App1View Modul 1 des instanziiert wird, ohne zu hart mit - Routen irgendwie manuell ordern oder neu zusammenstellen.

Ich hatte gehofft, dass dies ein allgemein genug Problem war, das das Angular-Team wahrscheinlich möglich gemacht hat mit etwas wie router.navigate([APP2_VIEW_ROUTE, ...other params]), wo man einfach das Route-Objekt übergeben kann RouterModule passend zum gewünschten Pfad verwendet. Mit Blick auf den Quellcode scheint dies jedoch keine Option zu sein. Stattdessen haben wir Beispiele für ActivatedRoute.

Das Problem mit ActivatedRoute (this.route unten) ist, dass es relativ zu App1View wird. Der Versuch, router.navigate(['m2SpecialId'],{relativeTo: this.route}) zu verwenden, ist ein Nicht-Starter, da es relativ zu dem Pfad ist, der uns zu App1View brachte, nicht zurück zu der bevorzugten Route von Modul 2 zu App2View. Die einzige andere, etwas elegante Route (Wortspiel) um diese Probleme, soweit ich das beurteilen kann, würde darin bestehen, das Modul jeder Unteranwendung als ModuleWithProviders zu importieren, so dass man optional das Modul des Moduls informieren kann Top-Level-Route auf seinen Zustand angewendet. Schreiben Sie dann Hilfsfunktionen auf, die URIs für diese Unteranwendung mithilfe der definierten Routen zusammenstellen.

Das fühlt sich sehr Kesselplatte ... wie vielleicht die Lösung oder Design-Muster bereits im Rahmen existiert, daher diese Frage.

Frage:

Gibt es ein Entwurfsmuster der Angular2 Router für die Verwendung, die Komponenten in andere Module importiert erlauben würde, sauber ihre eigenen Moduls vorkonfigurierte Routen verweisen, während eine flexible Top-Level-Route Definition beibehalten?

Antwort

3

Wenn Sie möchten Zugriff auf Ihre M2Component in M1 über Link, dann sollten Sie RouterModule verwenden und Modul2 nicht in Modul1 importieren.

Innen module1

RouterModule.forRoot([ 
    { 
     path: 'module2', 
     loadChildren: 'path-of-module2/module2.module#Module2Module' 
    } 
]) 

verwenden und in module2

RouterModule.forChild([ 
    { 
     path: '', 
     component: Module2Component 
    } 
]) 

Jetzt können Sie Module2Component von Route '/ module2' öffnen.

+0

Tatsächlich habe ich meinen Beitrag vergessen. Ab der aktuellen Version von Angular (4.0.x) ist dies der richtige Weg. Als ich im Oktober letzten Jahres zurückkam, war Angular ein 2.0-ish und meine Standardmethode schien der einzig praktikable Weg nach vorne zu sein. – Thomas

0

Hier ist die Lösung, die ich sagte klingt sehr Boilerplate. Es erfordert, dass Sie Ihre Unteranwendungsmodule mit einem Paar undurchsichtige Token einrichten: einen für Ihren URI und den anderen, um die Neukonfiguration dieses URI zu verhindern.

import { 
    NgModule, 
    OpaqueToken, 
    ModuleWithProviders, 
    Optional, 
    SkipSelf, 
    Inject 
} from '@angular/core'; 

export const ROOT_URI = new OpaqueToken('ROOT_URI'); 
export const URI_GUARD = new OpaqueToken('URI_GUARD'); 

Als nächstes müssen Sie definieren Ihr NgModule:

@NgModule({ /** ... as before ... */ }) 
export class SubApp1Module { 
    static configure(uri: string): ModuleWithProviders { 
     return { 
      ngModule: SubApp1Module, 
      providers: [ 
       { provide: ROOT_URI, useValue: uri }, 
       { provide: URI_GUARD, useFactory: provideGuard, 
        deps: [[ Object, new Optional(), new SkipSelf() ]] } 
      ] 
     }; 
    } 

    constructor(@Optional() @Inject(URI_GUARD) guard: any) { /** */ } 
} 

Die provideGuard Funktion:

export function provideGuard(something: any): any { 
    if (!something) { 
     return 'guarded'; 
    } else { 
     throw new Error('Do not attempt to configure this module more than once.'); 
    } 
} 

In Ihrem Modul, das diese sein importieren wird und die Konfiguration der RouterModule Routen, die letztlich Damit Sie in diese Unteranwendung gelangen, fügen Sie sie zu den Importen hinzu: imports: [ ..., SubApp1Module.configure(SPECIAL_ROOT_URL), ...].

In jeder Komponente/Richtlinie, die Sie in SubApp1Module haben, können Sie dieses Moduls greifen ROOT_URI durch Injektion:

import { Inject } from '@angular/core'; 
import { ROOT_URI } from './whatever/local/export/location'; 

// Down at the constructor 
constructor(@Inject(ROOT_URI) rootUri: string) { 
    console.log('This is my rootUri: ' + rootUri); 
} 

Nun, dies funktioniert und natürlich können Sie verwenden @Optional oder ? als geeignet für eine ermöglichen Standardwert, der injiziert werden soll. Dies funktioniert auch, wenn Sie einen Service oder eine Fabrik einspeisen, die Ihre Routen usw. auflöst, wenn Sie sich für diese Route entscheiden.

In mancher Hinsicht fühlt sich das wie der Angular Way ™ an (d. H., Mach es so). Wie Sie jedoch sehen können, ist es auch ziemlich beteiligt nur zu ermöglichen, Entitäten innerhalb eines Moduls zu innerhalb ihres eigenen Moduls zu routen obwohl in eine Komponente in einem anderen Modul ohne Hard-Coding-Pfade, etc. instanziiert

Verwandte Themen