Ich habe die folgenden Routing-Pfade für ein Modul meiner Angular App:
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'documents',
data: { myObject: MyConstants.OPTION_ONE },
children: [
{
path: ':ID_DOC',
children: [
{ path: 'edit', component: EditDocumentComponent },
{ path: '', component: DocumentDetailsComponent },
]
},
{ path: 'add', component: AddDocumentComponent },
{ path: '', component: DocumentsListComponent }
]
}
])
],
exports: [
RouterModule
]
})
export class DocumentsManagementRoutingModule {
}
Wie Sie sehen können, benutze ich die Eigenschaft data
, um Daten an jeden Pfad in "Dokumenten" zu übergeben, damit ich sie von einer der in den Routing-Pfaden deklarierten Komponenten erhalten kann:
Zum Beispiel ist hier, wie ich Daten in DocumentDetailsComponent
erhalte:
export class DocumentDetailsComponent implements OnDestroy {
private obsData: Subscription;
private option: any;
constructor(private route: ActivatedRoute) {
this.obsData = this.route.data.subscribe(data => {
this.option = data['myObject'];
});
}
ngOnDestroy(): void {
this.obsData.unsubscribe();
}
}
Jetzt habe ich die Routing-Struktur der gesamten App geändert und das obige Modul aus anderen Modulen mit dem loadChildren
-Attribut beim verzögerten Laden aufgerufen. Und ich übergebe Daten auf die gleiche Weise:
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'users',
loadChildren: 'app/documents/documents.module#DocumentsModule',
data: { myObject: MyConstants.OPTION_ONE }},
{
path: ':ID_USER',
children: [
{ path: 'edit', component: EditUserComponent },
{ path: '', component: UserDetailsComponent },
]
},
{ path: 'add', component: AddUserComponent },
{ path: '', component: UserListComponent }
])
],
exports: [
RouterModule
]
})
export class UsersManagementRoutingModule {
}
Und ich habe dasselbe für alle anderen Module getan, die DocumentsManagementRoutingModule
aufrufen, und die Eigenschaft myObject
entsprechend meinen Anforderungen in MyConstants.OPTION_TWO
, MyConstants.OPTION_THREE
Usw. geändert.
Wie erhalte ich dann die Eigenschaft data
vom Aufrufermodul, da ich das Modul und den zugehörigen Pfad, der mein Lazy Loading-Modul aufruft, nicht kenne?
Sie können die übergeordneten Routen mithilfe von activateRoute.pathFromRoot durchlaufen und die Daten von dem nächstgelegenen Vorfahren abrufen, bei dem sie verfügbar sind. So etwas scheint zu funktionieren:
ngOnInit(): void {
let idx = this.activatedRoute.pathFromRoot.length - 1;
while(this.sharedData == null && idx > 0){
this.sub = this.activatedRoute.pathFromRoot[idx].data.subscribe(subData => {
if(subData.id)
this.sharedData = subData;
console.log('shared data', this.sharedData);
});
idx--;
}
}
Ich glaube, ich kann verstehen, worum es bei der Frage geht.
Hier ist das Routing-Diagramm des Plunkers @smartmouse angegeben.
- home
- shop
- contact
- map
- about
In der Routenkonfiguration von data
ist ein home
Objekt konfiguriert. Die direkten untergeordneten Routen können auf dieses Datenobjekt zugreifen. Das Problem ist, dass das nicht direkte untergeordnete Objekt map
auf das Objekt data
zugreifen möchte, dies jedoch anscheinend nicht kann.
Und wir können wissen, dass @smartmouse Push möchte, dass verschachtelte nicht direkte untergeordnete Routen noch weiter auf Daten von Vorfahren zugreifen können .
Schau dir den Plunker an, den ich modifiziert habe. https://plnkr.co/edit/FA7mGmspUXHhU8YvgDpT
Sie können sehen, dass ich eine zusätzliche untergeordnete Komponente DefaultComponent
für contact
definiere. Es zeigt, dass es sich um das direkte und standardmäßige untergeordnete Element von route contact
handelt, was so interpretiert werden kann, dass es sich auch um das direkte untergeordnete Element von superior route home
handelt. Es kann also auf das Objekt data
zugreifen.
Schauen Sie sich noch einmal den von mir gelieferten Plunker an.
HINWEIS: Die von mir verwendeten Angular - Pakete sind v4.3.0
Ich definiere einige Abfrageparameter in home.component.ts
für contact
route. Sie können sehen, wie man es benutzt.
Vorteile :
Nachteile :
in route config können keine Abfrageparameter definiert werden.
Sie können jedoch einige Routen-Lifecycle-Hooks verwenden, um sie für die Routen der Zielvorfahren zu definieren
Definieren Sie einen Datenfreigabedienst auf oberster Ebene der Anwendung, die als Singleton-Muster abgespielt wird. Verwenden Sie auch ein wenig util, um zu verhindern, dass es zweimal gestartet wird. Dann können Sie einige Daten darin ablegen und überall abrufen.
Vorteile :
Nachteile :
Jemand könnte herausfinden, dass ich im Plunker auch resolve
Beispielcode definiert habe. Es soll zeigen, dass es dasselbe Verhalten hat wie data
in der Routenkonfiguration, außer dass es sich tatsächlich um das dynamische Abrufen von Daten handelt.
https://vsavkin.com/angular-router-understanding-router-state-7b5b95a12eab#54
Die Dateneigenschaft wird zum Übergeben eines festen Objekts an eine aktivierte Route verwendet. Sie ändert sich während der gesamten Lebensdauer der Anwendung nicht. Die Eigenschaft resolve wird für dynamische Daten verwendet.
Nehmen Sie das Beispiel von @ smartmouse.
Wir haben data
in der 'home'-Routenkonfiguration definiert. Wir können einen Daten-Resolver in ContactModule
für die Standardroute des Kontakts definieren und die von der übergeordneten Route übergebenen Daten als Proxy verwenden. Dann können alle ihre direkten untergeordneten Routen auf das Datenobjekt resolved zugreifen.
Vorteile :
Nachteile :
Derzeit gibt es keine perfekte und universelle Lösung mit der üblichen Verwendung von Angular. Jemand sollte die Vor- und Nachteile abwägen und das richtige auswählen.
Warum nutzen Sie den Service nicht, um die Daten zwischen den Modulen oder Komponenten auszutauschen? Sie können diesen Dienst beim Hauptmodulanbieter importieren lassen und können ihn daher in allen anderen Modulen (Lazy Loading Module) verwenden und die Daten gemeinsam nutzen.
Der Dienst kann Funktionen zum Festlegen und Abrufen von Werten enthalten. Daher können Sie diese Funktionen in Diensten verwenden, um die erforderlichen Daten abzurufen
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'users',
loadChildren: 'app/documents/documents.module#DocumentsModule',
resolve : {
data: DataResolver
}
{
])
],
exports: [
RouterModule
]
})
export class UsersManagementRoutingModule {
}
@Injectable()
export class DataResolverimplements Resolve<Data> {
resolve() {
return this.serice.getData();
}
}