在Angular2中,如何根据活动路径更改侧边栏?

时间:2016-08-23 18:52:37

标签: javascript angular typescript angular2-routing

我正在使用Angular 2(RC5)和Typescript编写SPA。我在顶部有一个主导航栏(使用Bootstrap 4 Alpha 3)和一个自定义设计的侧边栏。这是一张照片:

enter image description here

这里的目的是使用顶部导航栏导航到主“应用程序”。目前我有3个主要应用程序映射 - 跟踪器,Proboard和设备。激活主应用程序后,侧栏上的链接将发生变化。在上图中,侧边栏显示了“Proboard”应用程序的链接。

如何在我的HTML中没有一堆'* ngIf'声明的情况下,根据活动路径更改侧边栏的内容?

我想在我的代码中有一个JSON对象(可能从后端API检索),它会列出每个应用程序的链接。类似的东西:

[
  { proboard: [
    { label: 'Home', link: '/proboard', icon: 'fa-home'},
    { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'},
    { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } ]
  },
  { tracker: [...] },
  { equipment: [...] }
]

然后,当用户导航到顶部导航栏上的其中一个链接时,侧边栏将使用HTML中的NgFor填充上面数组中的内容。

任何建议或链接都​​将不胜感激。

5 个答案:

答案 0 :(得分:1)

这是一种可能的解决方案。

由于您的三个应用程序中的每个应用程序都是完全独立的(如您所定义的),您可以创建一个完全独立的“SideBarComponent”,您可以在每个应用程序中重复使用。

由于您可以使用@Input()变量为组件提供所需的任何信息,因此您可以为其提供所需的标签,链接和图标列表。例如:

EquipmentComponent.ts

sideBarLinks: any = { proboard: [
  { label: 'Home', link: '/proboard', icon: 'fa-home'},
  { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'},
  { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; } ]
}

EquipmentComponent.html

<side-bar [buttons]='sideBarLinks'></side-bar>

SideBarComponent.ts

@Input()
buttons: any;

SideBarComponent.html

// Use 'buttons' to construct your buttons in the sidebar. Possibly using an ng repeater in this template.

即使你最终没有完全实现这一点,我希望这会让你想到使用Angular 2的可重用组件。

希望这有用!

这不仅仅是您需要了解的有关组件互动的所有内容:https://angular.io/docs/ts/latest/cookbook/component-communication.html

答案 1 :(得分:1)

我做了同样的事情,这就是我如何解决它。

  1. 在最顶层的应用组件中创建了菜单
  2. 创建了一项服务并在服务中保留了一个公共路由表
  3. 创建了一个可订阅的主题流,用于更改路径
  4. 从菜单所在的组件订阅该流
  5. 从当前组件发出subcription.next,该组件使用菜单在组件中设置选定的路径。
  6. 您可以使用其他类型的组件交互来实现此目的。以下是Angular 2文档中的更多信息:https://angular.io/docs/ts/latest/cookbook/component-communication.html

答案 2 :(得分:1)

2种可能的方式

1 - 在侧边栏组件中,订阅路由器更改,但最终会使用*ngIf

@Input()
data: any;

constructor(private router: Router) {
    router.changes.subscribe((val) => {
        if(val === 'noSidebarRoute'){
            this.navButtons= false;
        }
        else {
            this.navButtons= navData;
        }
    })
}

然后在父组件模板

@Component({
    selector: 'parent',
    template: `<side-bar [data]='navData'></side-bar>`
});

export class Parent{

navData = [
     { proboard: [
       { label: 'Home', link: '/proboard', icon: 'fa-home'},
       { label: 'Candidates', link: '/proboard/candidates', icon: 'fa-users'},
       { label: 'New', link: '/proboard/candidate/new', icon: 'fa-new-user; }
     ]},
     { tracker: [...] },
     { equipment: [...] }
]}

2 - 在您的应用组件(或侧边栏父组件)中,使用resolver.resolveComponent动态地将侧边栏组件添加到您的应用中,这样您就不会使用数据绑定(*ngIf)。

sidebarCmpRef:ComponentRef<any>;

constructor(private router: Router,
            private viewContainerRef:ViewContainerRef,
            private resolver:ComponentResolver) {

    router.changes.subscribe((val) => {
        if(val === 'noSidebarRoute'){
            if(this.sidebarCmpRef){
               this.sidebarCmpRef.destroy();
               this.sidebarCmpRef
            }
        }
        else{
            this.AddSidebar();
        }
    })
}

AddSidebar(){
    if(!this.cmpRef){
        this.resolver.resolveComponent(<Type>SideBar)
          .then((factory:ComponentFactory<any>) => {
            this.cmpRef = this.viewContainerRef.createComponent(factory);
            this.cmpRef.instance.buttons= navData;
        });
    }
}

答案 3 :(得分:1)

我更愿意采用角度基本方法,即在路线内装载儿童。

按如下方式定义main.route

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PageNotFoundComponent } from './shared/components/pagenotfound.component';

export const appRoutes: Routes = [
  {
    path: 'tracker',
    loadChildren: 'app/tracker/module#trackermodule',
  },
  {
    path: 'proboard',
    loadChildren: 'app/proboard/module#proboard',
  },
 {
    path: 'equiment',
    loadChildren: 'app/equiment/module#equiment',
  },
  {
    path: '**',
    component: PageNotFoundComponent
  }
];

@NgModule({
    imports: [RouterModule.forRoot(appRoutes)],
    declarations: [
        PageNotFoundComponent
    ],
    exports: [RouterModule]
})

export class AppRouterModule {
}

然后在您的子/子模块中路由配置应该是

    import { RouterModule } from '@angular/router';
import {  CssComponent } from './view';
import { RadioAndCheckBoxComponent } from './radio-and-checkbox/view';

export const RouteComponents = [
  CssComponent
];

export const Routes = RouterModule.forChild([
  {
    path: '',
    component: equimentComponent,
    children: [
      {
        path: 'Home',
        component: HomeComoponent
      },
      {
        path: 'Candidates',
        component: CandidatesComoponent
      }
    ]
  }
]);

答案 4 :(得分:0)

我的情况相同(主菜单链接及其受尊敬的子菜单项),我已经按照以下方式进行了操作。

在根组件(app.component.ts)构造函数中,我订阅路由器事件,并基于重定向路由URL,隐藏并显示Main application子菜单。这是代码:

 this.router.events.subscribe(event => {
  if (event instanceof NavigationEnd) {

    this.currentUrl = event.urlAfterRedirects;
    console.log(event.urlAfterRedirects);

    if (this.currentUrl.includes("/MainMenuLink1")) {
      this.link1SubMenu = true;
      this.link2SubMenu = false;
    } else if (this.currentUrl.includes("/MainMenuLink2")) {
   this.link2SubMenu = true;
      this.link1SubMenu = false;
    }

  }
});

并基于该[link1SubMenu]布尔值,我使用* ngIf ='link1SubMenu'

显示和隐藏app.component.html中的Sub菜单。

它需要重构,但这是很快的胜利。