3

ユーザーが特定のページを表示しているときに、ナビゲーションを自動的に非表示にしようとしています。たとえば、ユーザーがログイン ページを表示している場合、メニューは表示されません。

これまでに試したことは、現在のページの URL パスに基づいて「ナビゲーションを表示」フラグを変更する Navigator サービスがあることです。これは、これまでのところ、次の URL を Navigator サービスに渡し、「ナビゲーションを表示」フラグを更新することを仕事としている App Guard によってアクセスされます。

テストとしては、クリックイベントを介してビューを更新して、サービスが正しいデータを受信し、それに応じて更新されていることを確認しています。

私が持っている唯一の問題は、「常に」「ナビゲーションを表示」フラグの変更を購読/聞く方法が思いつかないことです。つまり、ナビゲーションを自動的に隠して表示したいということです。

ナビゲーターサービス

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>

上記のテストでわかるように、サービスに登録できるように「ナビゲーションの切り替え」ボタンがあります。正直なところ、これが最良の実装であるかどうかはわかりません。また、正しい方法で行っていない可能性もあります。アプリ コンポーネントが「ナビゲーションを表示」フラグの値を常に認識できるようにする方法があるかどうかを尋ねたいと思います。

更新 - 問題は解決しました

私はこの質問に従って、正しく答えに導きました。次のようにナビゲーション サービスを更新しました。

ナビゲーターサービス

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ライフサイクル フックでサービスをサブスクライブします。

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