3

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

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

就测试而言,我正在通过单击事件更新视图,以检查服务是否接收到正确的数据并进行相应更新。

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

导航服务

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;
        }
    }
}

应用卫士

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);
    }
}

应用组件

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);
    }
}

应用组件模板

<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 组件始终知道“显示导航”标志的值。

更新 - 问题已解决

我已经按照这个问题正确地引导我找到答案。我更新了导航服务如下:

导航服务

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);
    }
}

ngOnInit然后我在 App 组件的生命周期钩子中订阅了该服务:

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% 确定这是否是最好的方法,但到目前为止它已经解决了我的问题。

4

1 回答 1

2

供其他人参考,您只需使用路由器即可。我在下面有一个示例,其中我<router-outlet></router-outlet>在 AppComponent 的模板中只有一个,并将您想要隐藏的所有内容移动到一个名为 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: ''}
])
于 2017-07-11T15:54:07.647 回答