如何在angular 2中创建动态菜单?

如何在angular 2中创建动态菜单?,angular,angular2-template,angular2-services,Angular,Angular2 Template,Angular2 Services,我需要在用户成功登录并使用Angular 2重定向到主页后创建一个动态菜单。与第一个类似的问题完全一样,只是我不能硬核菜单项 #app.component.html# **home.component.ts** 从“@angular/core”导入{Component,OnInit}; 从“../\u模型/索引”导入{User}; 从“../\u services/index”导入{UserService}; @组成部分({ //moduleId:module.id, templateUrl:

我需要在用户成功登录并使用Angular 2重定向到主页后创建一个动态菜单。与第一个类似的问题完全一样,只是我不能硬核菜单项

#app.component.html#
**home.component.ts**
从“@angular/core”导入{Component,OnInit};
从“../\u模型/索引”导入{User};
从“../\u services/index”导入{UserService};
@组成部分({
//moduleId:module.id,
templateUrl:'home.component.html'
})
导出类HomeComponent实现OnInit{
用户:用户[]=[];
构造函数(私有用户服务:用户服务){}
恩戈尼尼特(){
//从安全api端点获取用户
this.userService.getUsers()
.订阅(用户=>{
this.users=用户;
});
}
}
显然,我对这项技术还不熟悉。有人来拿这个吗


Blockquote

以下是我的工作。基本上,流程是在应用程序组件中设置一个监听器,订阅getLoggedIn的可观察项。当可观察到的发射(用户登录)时,我调用app.menu.service get loggin menu。注销时,反过来是真的,我得到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() {
    }
}
登录服务:

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

在用户登录后,我根据用户访问权限创建了动态菜单。我想我无法在最初的问题中正确地表达要求。昨天,在搜索“如何使两个组件相互通信”时,我在angular网站上找到了以下内容(参见下面的链接):

我们可以通过使用全局EventEmitter来实现这一点。以下是我如何在代码中实现它:

GlobalEventManager:

import { Injectable, EventEmitter } from "@angular/core";

@Injectable()
export class GlobalEventsManager {
    public showNavBar: EventEmitter<any> = new EventEmitter();
    public hideNavBar: EventEmitter<any> = new EventEmitter();
}
menu.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() {
    }
}
特点:

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 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">
        &nbsp;
    </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 { }
从'@angular/core'导入{Component,OnInit};
从'@angular/Router'导入{Router};
从“../\u模型/特征”导入{Features};
从'@angular/Http'导入{Http,Headers,RequestOptions,Response};
从“./_common/gobal events manager”导入{GlobalEventsManager}”;
@组成部分({
选择器:“导航”,
templateUrl:“./menu.component.html”
})
导出类菜单组件{
showNavBar:boolean=false;
功能列表:功能[]=[];
私有头=新头({'Content-Type':'application/json'});
构造函数(专用http:http,专用路由器:路由器,专用globalEventsManager:globalEventsManager){
this.globalEventsManager.showNavBar.subscribe((模式:any)=>{
this.showNavBar=模式;
如果(this.showNavBar=true){
this.getFeatureListByLoggedInUser(1)
.then(list=>{this.featureList=list;});
}
});
this.globalEventsManager.hideNavBar.subscribe((模式:any)=>{
this.showNavBar=false;
this.featureList=[];
});
}
私有getFeatureListByLoggedInUser(用户ID:number):承诺{
返回此.http.get(您的api url+'/Feature/GetFeatureListByUserID?userID='+userID)
.toPromise()
.then(response=>response.json()作为特性[])
.接住(这个.把手错误);
}
私有句柄错误(错误:任意):承诺{
console.error('发生错误',error);//仅用于演示目的
返回承诺。拒绝(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>

    {{feature.description}
App.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 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">
        &nbsp;
    </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 { }

最后,我们需要在app.module.ts中注册菜单和全局事件管理器的提供者
app.module.ts
/// 
/// 
导入“/rxjs扩展名”;
从'@angular/core'导入{NgModule,ErrorHandler};
从“@angular/platform browser”导入{BrowserModule};
从'@angular/forms'导入{FormsModule,ReactiveFormsModule};
从'@angular/http'导入{HttpModule,XHRBackend};
从“./app routing.module”导入{AppRoutingModule};
从“./app.component”导入{AppComponent};
从“/_guards/auth.guard”导入{AuthGuard};
从“/_common/headers”导入{ContentHeaders};
从“/_common/gobal events manager”导入{GlobalEventsManager}”;
从“/menu/menu.component”导入{MenuComponent};
@NGD模块({
进口:[
浏览器模块,
FormsModule,
HttpModule,
批准模块,
反应窗体模块
],
声明:[
应用组件,
菜单组件
],
供应商:[
AuthGuard,
ContentHeaders,
全球财务经理
],
引导:[AppComponent]
})
导出类AppModule{}

我希望这会有帮助

我是通过基于用户权限的过滤器运行菜单项数组来实现的。

嗨,约翰,谢谢你的早期回复。但这并不能解决我的问题。实际上,我想根据用户的权限创建一个动态菜单,在angular 2中?导航栏位于app.component.html中,但我需要通过home.component.ts文件创建。“我希望你现在明白了。”下一个投票人,能解释下一个投票吗?