首页 文章

Angular 2基于路线隐藏某些页面上的导航

提问于
浏览
2

我正试图在用户查看某些页面时自动隐藏导航 . 例如,如果用户正在查看登录页面,则不应显示菜单 .

到目前为止我尝试过的是我有一个Navigator服务,它将根据当前页面的URL路径更改“show navigation”标志 . 这可以通过App Guard访问,其目前的工作是将下一个URL传递给Navigator服务并更新“show navigation”标志 .

到目前为止测试我通过点击事件更新视图以检查服务是否正在接收正确的数据并相应地更新 .

我唯一的问题是我无法想到一种方式来“一直”订阅/收听“show navigation”标志的变化 . 我的意思是我希望导航被隐藏并自动显示 .

Navigator Service

import { Injectable } from '@angular/core';

import { Observable } from 'rxjs/Observable';

@Injectable()
export class NavigatorService {
    private showNavigation: boolean = false;

    displayNavigation(): Observable<boolean> {
        return Observable.of(this.showNavigation);
    }

    toggleNavigation(urlPath: string) {
        if (urlPath === 'login') {
            this.showNavigation = false;
        } else {
            this.showNavigation = true;
        }
    }
}

App Guard

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';

import { Observable } from 'rxjs/Observable';

import { NavigatorService } from '../services';

@Injectable()
export class AppGuard implements CanActivate {
    constructor(private navigatorService: NavigatorService) { }

    canActivate(next: ActivatedRouteSnapshot) {
        console.log(next);

        this.navigatorService.toggleNavigation(next.url[0].path);

        // for now returning Observable of true...
        // will be changed when extra functionality is added
        return Observable.of(true);
    }
}

App Component

import { Component } from '@angular/core';

import { NavigatorService } from './shared';


@Component({
    selector: 'app',
    styleUrls: [
        './app.style.css'
    ],
    template: require('./app.component.html')
})
export class AppComponent {
    showNavigation: boolean = true;

    constructor(private navigatorService: NavigatorService) { }

    // button click event
    toggleNav() {
        this.navigatorService.displayNavigation
            .subscribe(res => this.showNavigation = res);
    }
}

App Component Template

<button (click)="toggleNav()">Toggle Navigation</button>
<div id="page-wrapper">
    <div id="sidebar-wrapper" *ngIf="showNavigation">
        <navigation></navigation>
    </div>
    <div id="page-content-wrapper">
        <main>
            <router-outlet></router-outlet>
        </main>
    </div>
</div>

从上面作为测试可以看出,我有一个“切换导航”按钮,以便我可以订阅该服务 . 说实话,我不知道这是不是最好的实现,也许我不是以正确的方式去做 . 我想问一下,是否有某种方式App组件始终会知道“show navigation”标志的值 .

Update - Issue resolved

我跟着这个question正确地引导我回答 . 我更新了导航服务,如下所示:

Navigator Service

import { Injectable } from '@angular/core';

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class NavigatorService {
    private showNavigation: Subject<boolean>;

    constructor() {
        this.showNavigation = <Subject<boolean>>new Subject();
    }

    get displayNavigation(): Observable<boolean> {
        return this.showNavigation.asObservable();
    }

    toggleNavigation(urlPath: string) {
        let showNav: boolean;
        if (urlPath === 'login') {
            showNav = false;
        } else {
            showNav = true;
        }

        this.showNavigation.next(showNav);
    }
}

然后我订阅App Component的 ngOnInit 生命周期钩子中的服务:

import { Component, OnInit } from '@angular/core';

import { NavigatorService } from './shared';

@Component({
    selector: 'app',
    styleUrls: [
        './app.style.css'
    ],
    template: require('./app.component.html')
})
export class AppComponent implements OnInit {
    showNavigation: boolean = true;

    constructor(private navigatorService: NavigatorService) { }

    ngOnInit() {
        this.navigatorService.displayNavigation
            .subscribe(res => this.showNavigation = res);
    }
}

如果这是最好的方法,我仍然不能100%确定它,但到目前为止它解决了我的问题 .

1 回答

  • 0

    对于其他人的参考,您可以使用路由器执行此操作 . 我在下面有一个示例,其中我在AppComponent的模板中只有一个 <router-outlet></router-outlet> ,并将您想要隐藏的所有内容移动到名为DefaultLayoutComponent的单独布局视图中 .

    将您的菜单/页脚和 <router-outlet></router-outlet> 放在DefaultLayoutComponent中 . 现在,只有DefaultLayoutComponent的子项(即下面的仪表板和邀请组件)才具有公共布局 . 其他页面(即下面的登录)将具有空白布局 .

    RouterModule.forRoot([
      { path: 'login', component: LoginComponent},
        { path: '', component: DefaultLayoutComponent, children: [
          { path: '', component: DashboardComponent},
          { path: 'dashboard', component: DashboardComponent },
          { path: 'invite', component: InviteComponent}]
        },
      { path: '**', redirectTo: ''}
    ])
    

相关问题