2017-01-30 6 views
3

Ich habe eine Anwendung, die authentifizierte und Gastbenutzer Komponenten trennen müssen. Aber ich brauche, dass beide Komponenten von '/' Route geladen werden. Ich schriebAngular 2 verschiedene Komponenten mit der gleichen Route

{ 
    path: 'desktop', 
    loadChildren: 'app/member/member.module#MemberModule', 
    canActivate: [LoggedInGuard], 
}, 
{ 
    path: '', 
    loadChildren: 'app/guest/guest.module#GuestModule', 
    canActivate: [GuestGuard], 
}, 

Und es funktioniert. Aber wie kann man machen, dass beide Komponenten von derselben URL geladen werden? Ich hatte versucht, path: '' für die Modulroute des Mitglieds zu schreiben, aber die zweite Router-Regel wird nicht ausgeführt. Hier sind Wächter Code:

LoggedInGuard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 
    if(this.sessionService.isLoggedIn()) { 
     return true; 
    } else { 
     return false; 
    } 
} 

GuestGuard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 
    if(!this.sessionService.isLoggedIn()) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Hier ist ein Plunker: http://embed.plnkr.co/VaiibEVGE79QU8toWSg6/

Wie soll ich es richtig machen? Vielen Dank.

+0

Was ist der Fehler? – echonax

+0

Es tut mir leid. Es gibt keinen Fehler. Aber nur die erste Router-Regel durchgeführt –

+0

Wenn es keinen Fehler gibt und die erste Router-Regel erfüllt ist, dann ist Ihr LoggedInGuard wahr geworden? – echonax

Antwort

-1

Eine Möglichkeit, dies zu tun, ist die Weiterleitung an den entsprechenden Bereich, je nachdem, ob der Benutzer angemeldet ist oder nicht.

(dh ob Sie leere Route oder Gast Route öffnen, wird es entsprechend weitergeleitet und Zurück-Taste funktioniert nicht)

Routen:

{ 
    path: '', 
    loadChildren: 'app/member/member.module#MemberModule', 
    canActivate: [LoggedInGuard], 
}, 
{ 
    path: 'guest', 
    loadChildren: 'app/guest/guest.module#GuestModule', 
    canActivate: [GuestGuard], 
} 

LoggedInGuard::

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 
    if(this.sessionService.isLoggedIn()) { 
     return true; 
    } else { 
     // route to 'guest' if not logged in 
     this.router.navigate(['/guest'], { replaceUrl: true }); 
     return false; 
    } 
} 

GuestGuard(wenn mit automatischer Route zu MemberComponent angemeldet):

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 
    if(this.sessionService.isLoggedIn()) { 
     // route to member area if already logged in 
     this.router.navigate(['/'], { replaceUrl: true }); 
     return false; 
    } else { 
     return true; 
    } 
} 
+0

OP möchte, dass beide die gleiche Route haben: "Aber ich brauche, dass beide Komponenten von '/' Route geladen werden." – echonax

+0

@echonax Sie können nicht verschiedene Module mit demselben Routenpfad laden (auch wenn sie mit verschiedenen Schutzeinrichtungen ausgestattet sind). Die einzige Möglichkeit besteht darin, etwas wie oben zu tun, wobei unabhängig davon, welcher Pfad geöffnet ist, der Benutzer korrekt umgeleitet wird. –

1

So war ich endlich in der Lage, dies zu tun. Die Sache ist, dass Angular die First-Match-Policy verwendet, also müssen wir die Routen wächterartig abgleichen, um sicherzustellen, dass die richtige Route mit dem richtigen Modul übereinstimmt.

Als erstes müssen wir benutzerdefinierte matchers für unsere Routen hinzufügen, die nur unter Bedingungen treffen, die wir wollen (zB Benutzertyp).

{ 
path: 'samePath', 
matcher: firstMatcher, 
loadChildren: '../first/first.module#FirstModule' 
}, 
{ 
path: 'samePath', 
matcher: secondMatcher, 
loadChildren: '../second/second.module#SecondModule' 
} 

Und Matcher-Code ist so etwas wie dieses: In here i AuthService Service von AppModule injiziert und überprüft Benutzer mit ihm geben. So können Routen nach Benutzertyp angepasst werden.

import { applicationInjector } from '../../main'; 

export function firstMatcher (url: UrlSegment[]) { 
    const auth = applicationInjector.get(AuthService); 
    return auth.isUserType('admin') ? ({consumed: [url[0]]}) : null; 
} 

Und jetzt nur, was wir brauchen, ist applicationInjector in unserem Hauptmodul zu schaffen, und so konnten wir Service in unserer Matcher-Funktion injizieren;

export let applicationInjector: Injector; 

platformBrowserDynamic().bootstrapModule(AppModule).then((componentRef) => { 
    applicationInjector = componentRef.injector; 
}) 
Verwandte Themen