2016-05-03 6 views
1

Mein Problem ist folgendes zu verstecken:anhand beobachtbarer Navbar in Angular 2

Ich habe ein navbar in meinem app.component und ich möchte, dass zum Beispiel verstecken vor dem jemand mit ngIf, indem Sie einfach eine boolean Variable auf true angemeldet .

app.component.html:

<navbar *ngIf="_userLoggedIn === true" ></navbar> 
<router-outlet></router-outlet> 

Nachdem durch Web-Suche und Lesen durch Tonnen von Fragen hier denke ich, sollte dies mit Observable erfolgen. Aber ich kann nicht herausfinden, wie man sie auf eine gute Weise benutzt. Meine Idee war, ein Observable in einem globalen Service zu verwenden, um eine Variable zu teilen, so dass child component auf diese Variable zugreifen und bearbeiten kann und die app.component diese Variable abonnieren kann, um _userLoggedIn zu ändern (true), wenn diese Observable auf true gesetzt ist.

ich mit login.component mit der angular2 Router so seine im

<router-outlet> angezeigt
{ 
     path: '/login', 
     name: 'Login', 
     component: LoginComponent, 
     useAsDefault: true 
    }, 

In dieser Komponente möchte ich nach successed Login diese Variable auf true setzen. So ändert sich in app.component und die Navbar wird angezeigt. Wenn Sie weiteren Code benötigen, sagen Sie es mir einfach.

Wäre toll, wenn jemand von mir mir bei meinem Problem helfen oder eine alternative Lösung für mein Problem bekommen könnte.

Antwort

3

hatte ich ein ähnliches Problem und stellte die Frage hier: How to manipulate a component on specific routes in Angular2

Das Hauptproblem ist (das ist, warum ich nicht empfehlen @CanActivate oder onActivate verwenden), die Sie nur diese Router utils auf Komponenten verwenden können, die geroutet werden TO, nicht VON. Wenn Sie zum Beispiel eine Topbar oder Sidebar in Ihrer app.component haben, die Ihre router-outlet in ihrer Vorlage hat, können Sie einfach nicht auf route Data zugreifen.

Deshalb können Sie einfach den Standard router-outlet erweitern und Ihre Logik dort hineinlegen.

Mit einem @RouteConfig wie folgt aussehen:

@RouteConfig([ 
{ 
    path: '/login', 
    name: 'Login', 
    component: LoginComponent, 
    data: { 
     hideTopbar: true, 
     hideSidebar: true 
    } 
}, 

und eine Vorlage für Ihre app.component suchen etwas wie folgt aus:

<div class="topbar" *ngIf="showTopbar">...</div> 
<extended-router-outlet></extended-router-outlet> 

Sie dies in Ihrer app.component Klasse verwalten:

export class AppComponent { 
    showTopbar:boolean; 
    showSidebar:boolean; 

    constructor(private _routingEventService:RoutingEventService) { 
     this._routingEventService.onRouteChanged().subscribe(routeData => { 
      this.showTopbar = !routeData.hideTopbar; 
      this.showSidebar = !routeData.hideSidebar; 
     }); 
    } 
} 

mit einem injected routingEventService l ike in der akzeptierte Antwort i oben verlinkten:

@Injectable() 
export class RoutingEventService { 
    private _eventEmitter: EventEmitter<any> = new EventEmitter(); 

    routeIsChanging(obj:any) { 
     this._eventEmitter.emit(obj); 
    } 

    onRouteChanged() { 
     return this._eventEmitter; 
    } 
} 

Und dann endlich, bauen Sie Ihre Logik in Ihrer neuen router-outlet Richtlinie wie folgt aus:

@Directive({ 
    selector: 'extended-router-outlet' 
}) 

export class ExtendedRouterOutlet extends RouterOutlet { 
    private parentRouter:Router; 

    constructor(_elementRef: ElementRef, 
       _loader: DynamicComponentLoader, 
       _parentRouter: Router, 
       @Attribute('name') nameAttr: string, 
       private _routingEventService:RoutingEventService) { 
     super(_elementRef, _loader, _parentRouter, nameAttr); 
     this.parentRouter = _parentRouter; 
    } 

    activate(nextInstruction: ComponentInstruction): Promise<any> { 
     this._routingEventService.routeIsChanging({ 
      name: nextInstruction.routeName, 
      hideTopbar: nextInstruction.routeData.data['hideTopbar'], 
      hideSidebar: nextInstruction.routeData.data['hideSidebar'] 
     }); 
     return super.activate(nextInstruction); 
    } 
} 

Mit diesem Ansatz können Sie auch andere Route spezifische Logik behandeln , beispielsweise Authentifizierung oder Rollen zu überprüfen, wie ich hier mit dem gleichen Ansatz in meiner Antwort auf die folgende Frage erklärt:

Fill form after http response in angular2

Hoffe es hilft.

+0

Es hat eine Weile gedauert, das zu verstehen, weil ich relativ neu zu angular2 bin, aber danach hat es ziemlich gut für mich funktioniert. Vielen Dank @lexith für Ihre schnelle und gute Antwort. Du hast mir sehr geholfen! – marvstar

+0

Gern geschehen. Fyi: Sie sollten dies jedoch als Problemumgehung sehen. der router bekommt immer mehr liebe aus dem ng-team und wird es in zukunft erleichtern. Ein Kollege von mir hat mir gerade gesagt, dass er für dieses Szenario eine One-Liner-Lösung gefunden hat, indem er den Router abonniert hat, aber ich hatte noch nicht die Zeit, mich darum zu kümmern. – lexith

+0

Danke für diese Info. Wir werden sehen, wie wir damit umgehen sollen, wenn Angular2 endgültig ist. Aber es wäre großartig, wenn Sie mir mitteilen könnten, ob es einen besseren oder vielleicht einfacheren Weg gibt, dies zu tun. – marvstar