ユーザーが正常にログインし、Angular 2.を使用してホームページにリダイレクトした後、動的メニューを作成する必要があります。
Angular2:ルートを使用して、ログインに成功した後にナビゲーションバーを表示する方法?
#app.component.html#
<navbar>
<!--Here I want to create menu items-->
</navbar>
<div class="container">
<div class="col-sm-12">
<router-outlet></router-outlet>
</div>
</div>
<div id="footer" class="inner-wrap">
<div class="row no-padding">
<div class="col-sm-12 no-padding">
</div>
</div>
</div>
**home.component.ts**
import { Component, OnInit } from '@angular/core';
import { User } from '../_models/index';
import { UserService } from '../_services/index';
@Component({
//moduleId: module.id,
templateUrl: 'home.component.html'
})
export class HomeComponent implements OnInit {
users: User[] = [];
constructor(private userService: UserService) { }
ngOnInit() {
<!-- how we can create it here or any better place -->
// get users from secure api end point
this.userService.getUsers()
.subscribe(users => {
this.users = users;
});
}
}
明らかに、私はこの技術に慣れていない。誰かこれを拾ってください?
ブロッククォート
ユーザーがログインした直後に、ユーザーアクセスに基づいて動的メニューを作成することができました。元の質問では要件を適切に明確にすることができなかったと思います。昨日、「2つのコンポーネントを相互に通信させる方法」を検索中に、angularウェブサイト(以下のリンクを参照)でこれを見つけました。
https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html
これを実現するには、Global EventEmitterを使用します。コードに実装する方法は次のとおりです。
GlobalEventManager:
import { Injectable, EventEmitter } from "@angular/core";
@Injectable()
export class GlobalEventsManager {
public showNavBar: EventEmitter<any> = new EventEmitter();
public hideNavBar: EventEmitter<any> = new EventEmitter();
}
以下のリンクは、認証ガードを実装する方法を理解するのに役立ちます(ログインせずに入力するユーザーを制限します)。
http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial
Auth.Guard.ts:
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { GlobalEventsManager } from "../_common/gobal-events-manager";
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private globalEventsManager: GlobalEventsManager) { }
canActivate() {
if (localStorage.getItem('currentUser')) {
this.globalEventsManager.showNavBar.emit(true);
return true;
}
else {
// not logged in so redirect to login page
this.router.navigate(['/login']);
this.globalEventsManager.hideNavBar.emit(true);
return;
}
}
}
Menu.component.tsで使用されるモデル
特徴:
export class Features {
Description: string;
RoutePath: string;
}
menu.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Features } from '../_models/features';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { GlobalEventsManager } from "../_common/gobal-events-manager";
@Component({
selector: 'nav',
templateUrl: './menu.component.html'
})
export class MenuComponent {
showNavBar: boolean = false;
featureList: Features[] = [];
private headers = new Headers({ 'Content-Type': 'application/json' });
constructor(private http: Http, private router: Router, private globalEventsManager: GlobalEventsManager) {
this.globalEventsManager.showNavBar.subscribe((mode: any) => {
this.showNavBar = mode;
if (this.showNavBar = true) {
<!-- the below function expects user id, here I have given as 1 -->
this.getFeatureListByLoggedInUser(1)
.then(list => { this.featureList = list; });
}
});
this.globalEventsManager.hideNavBar.subscribe((mode: any) => {
this.showNavBar = false;
this.featureList = [];
});
}
private getFeatureListByLoggedInUser(userID: number): Promise<Features[]> {
return this.http.get(your api url + '/Feature/GetFeatureListByUserID?userID=' + userID)
.toPromise()
.then(response => response.json() as Features[])
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
}
Menu.Component.html:
<div id="navbar" *ngIf="showNavBar" class="navbar-collapse collapse navbar-collapse-custom">
<ul class="nav navbar-nav nav_menu full-width">
<li *ngFor="let feature of featureList" class="nav_menu" routerLinkActive="active"><a class="nav-item nav-link" [routerLink]="[feature.routepath]" routerLinkActive="active">{{feature.description}}</a></li>
</ul>
</div>
App.Component.ts:
<!-- menu container -->
<nav>
</nav>
<!-- main app container -->
<div class="container-fluid body-content-custom">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 no-padding">
<router-outlet></router-outlet>
</div>
</div>
<footer class="footer">
</footer>
In the last, we need to register the providers of menu and global event manager in app.module.ts
app.module.ts
/// <reference path="reset-password/reset-password.component.ts" />
/// <reference path="reset-password/reset-password.component.ts" />
import './rxjs-extensions';
import { NgModule, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, XHRBackend } from '@angular/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthGuard } from './_guards/auth.guard';
import { ContentHeaders } from './_common/headers';
import { GlobalEventsManager } from "./_common/gobal-events-manager";
import { MenuComponent } from "./menu/menu.component";
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
AppRoutingModule,
ReactiveFormsModule
],
declarations: [
AppComponent,
MenuComponent
],
providers: [
AuthGuard,
ContentHeaders,
GlobalEventsManager
],
bootstrap: [AppComponent]
})
export class AppModule { }
これが役立つことを願っています!
これが私がやることです。基本的に、フローは、getLoggedInのオブザーバブルにサブスクライブするアプリコンポーネントのリスナーを設定します。そのオブザーバブルが発行される(ユーザーがログインする)とき、app.menu.service get callメニューを呼び出します。ログアウトすると、逆のことが起こり、noLoginMenuが表示されます。
app.menu.service:
import {RouterModule, RouterLinkActive, RouterLink} from '@angular/router';
import {Injectable} from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs';
@Injectable()
export class AppMenuService {
constructor() {
}
getNoLoginMenu() {
return [
{
label: 'Home',
routerLink: ['']
}, {
label: 'Documents',
routerLink: ['/document']
}, {
label: 'Calculator',
routerLink: ['/calculator']
}, {
label: 'Verify',
routerLink: ['/verify']
}, {
label: 'About',
routerLink: ['/about']
}];
}
getLoggedInMenu() {
return [
{
label: 'Home',
routerLink: ['']
}, {
label: 'Documents',
routerLink: ['/document']
}, {
label: 'Food',
routerLink: ['/food']
}, {
label: 'Calculator',
routerLink: ['/calculator']
}, {
label: 'Settings',
routerLink: ['/settings']
}, {
label: 'Themes',
routerLink: ['/themes']
}, {
label: 'About',
routerLink: ['/about']
}, {
label: 'Logout',
routerLink: ['/logout']
//command: (event: Event) => { this.onLogout() }
}];
}
}
app.component.ts
export class AppComponent implements OnInit, OnDestroy {
private items: MenuItem[];
appPageHeaderDivStyle: {};
selectedTheme: Theme;
errorMessage: string;
loggedIn: LoggedIn;
loggedInEmail: string = "";
isLoggedIn: boolean;
themeSub: Subscription;
loggedInSub: Subscription;
profileSub: Subscription;
constructor(
private as: AppMenuService,
private ts: ThemeService,
private ss: SettingsService,
private fs: FoodService,
private ls: LoginService) {
}
@HostListener('window:beforeunload', ['$event'])
beforeUnloadHander(event) {
var shutdown = this.onShutdown();
//event.preventDefault();
}
ngOnInit() {
this.themeSub = this.ts.getNewTheme()
.subscribe(
theme => this.selectedTheme = theme,
error => {
this.errorMessage = error
},
() => this.completeGetNewTheme()
);
this.ts.setTheme("Pepper-Grinder");
this.items = this.as.getNoLoginMenu();
this.ls.getLoggedIn()
.subscribe(
loggedIn => {
if (loggedIn.error != undefined && loggedIn.error === "" && loggedIn.email != "") {
this.items = this.as.getLoggedInMenu();
var us = this.ss.getUserSettings();
if (us != undefined && us.theme != null && us.theme != "") {
this.ts.setTheme(us.theme);
}
}
else {
this.items = this.as.getNoLoginMenu();
this.ts.setTheme("Pepper-Grinder");
}
this.completeLoggedIn(loggedIn.email);
});
}
ngOnDestroy() {
if (this.themeSub) {
this.themeSub.unsubscribe();
}
if(this.loggedInSub) {
this.loggedInSub.unsubscribe();
}
if(this.profileSub) {
this.profileSub.unsubscribe();
}
}
completeLoggedIn(email: string) {
this.loggedInEmail = email;
this.isLoggedIn = (this.loggedInEmail.length > 0);
}
completeGetNewTheme() {
this.appPageHeaderDivStyle = this.ts.getAppPageHeaderDivStyle();
}
onShutdown(): boolean {
var ok = true;
this.fs.completeUpdateDailyFood();
this.profileSub = this.ss.updateProfileInformation(this.ss.getUserSettings())
.subscribe(
status => {
console.log("logout - updated user");
},
error => {
ok = false;
},
);
return ok;
}
onLogout() {
}
}
LoginService:
loginUser(localUser: LocalUser) {
this.authSub = this.auth.loginUser(localUser)
.subscribe(
token => {
this.token = token
},
error => {
this.isLoggingIn = false;
var errorObject = JSON.parse(error._body);
this.errorMessage = errorObject.error_description;
console.log(this.errorMessage);
this.setLoggedIn({ email: "", password: "", error: this.errorMessage });
},
() => this.completeLogin(localUser));
}
これを行うには、ユーザーの権限に基づいてフィルターを介してメニュー項目配列を実行しました。 Array.prototype.filter()