-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
Description
Hi guys,
here is a small module I use for my projects:
// index.ts
export * from './navbar-item-abstract.class';
export * from './navbar-header.class';
export * from './navbar-item.class';
export * from './navbar-separator.class';
// navbar-header.class.ts
import { NavbarItemAbstract } from './navbar-item-abstract.class';
export class NavbarHeader extends NavbarItemAbstract {
public type = 'header';
constructor(public headerText: string) {
super();
}
}
// navbar-item-abstract.class.ts
export abstract class NavbarItemAbstract {
public abstract type: string;
}
// navbar-item.class.ts
import { NavbarItemAbstract } from './navbar-item-abstract.class';
export class NavbarItem extends NavbarItemAbstract {
public type = 'item';
constructor(
private name: string,
private options?: {
iconClass?: string; // icon is not supported yet
routerLink?: any[];
externalLink?: {
url: string;
target: string;
};
subnavigation?: NavbarItemAbstract[];
}
) {
super();
this.options = this.options || {};
if (this.options.externalLink) {
this.options.externalLink.target = this.options.externalLink.target || '_self';
}
}
public get iconClass() {
return this.options.iconClass;
}
public get routerLink() {
return this.options.routerLink;
}
public get externalLink() {
return this.options.externalLink;
}
public get subnavigation() {
return this.options.subnavigation;
}
}
// navbar-items.component.ts
import { Component, Input } from '@angular/core';
import { NavbarItemAbstract } from './navbar-item-abstract.class';
@Component({
selector: '[navbarItems]',
template: `
<template ngFor let-item [ngForOf]="navbarItems">
<li *ngIf="!item.subnavigation || !item.subnavigation.length" routerLinkActive="active">
<a *ngIf="item.routerLink" [routerLink]="item.routerLink">{{ item.name }}</a>
<a *ngIf="item.externalLink" [href]="item.externalLink.url" [target]="item.externalLink.target">{{ item.name }}</a>
</li>
<li *ngIf="item.subnavigation && item.subnavigation.length" class="dropdown" dropdown>
<a dropdownToggle class="dropdown-toggle" role="button" aria-haspopup="true">
{{ item.name }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<template ngFor let-subItem [ngForOf]="item.subnavigation">
<li *ngIf="subItem.type === 'item'" routerLinkActive="active">
<a *ngIf="subItem.routerLink" [routerLink]="subItem.routerLink">{{ subItem.name }}</a>
<a *ngIf="subItem.externalLink" [href]="subItem.externalLink.url" [target]="subItem.externalLink.target">{{ subItem.name }}</a>
</li>
<li *ngIf="subItem.type === 'separator'" role="separator" class="divider"></li>
<li *ngIf="subItem.type === 'header'" class="dropdown-header">{{ subItem.headerText }}</li>
</template>
</ul>
</li>
</template>
`
})
export class NavbarItemsComponent {
@Input()
public navbarItems: NavbarItemAbstract[];
}
// navbar-separator.class.ts
import { NavbarItemAbstract } from './navbar-item-abstract.class';
export class NavbarSeparator extends NavbarItemAbstract {
public type = 'separator';
constructor() {
super();
}
}
// and finally navbar.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { DropdownModule } from 'ng2-bootstrap';
import { NavbarItemsComponent } from './navbar-items.component';
@NgModule({
declarations: [
NavbarItemsComponent
],
imports: [
CommonModule,
RouterModule,
DropdownModule
],
exports: [
NavbarItemsComponent
]
})
export class NavbarModule {}What it does: it allows a navbar configuration right inside of the component without writing HTML.
Why it is useful: when it is about more than 10 menu items the HTML becomes unreadable and unsupportable. Also it is useful to avoid the repetitions, e.g. adding rights check for every li item is really annoying while configuring it inside of controller is damn easy.
Usage example:
Component:
public ngOnInit() {
this.navigationItems = [
new NavbarItem('Content', { subnavigation: [
new NavbarHeader('Content'),
new NavbarItem('Menu', { routerLink: ['menu'] }),
new NavbarItem('Pages', { routerLink: ['pages'] }),
new NavbarSeparator(),
new NavbarHeader('Global parts'),
new NavbarItem('Header', { routerLink: ['header'] }),
new NavbarItem('Footer', { routerLink: ['footer'] })
]}),
new NavbarItem('Assets', { subnavigation: [
new NavbarItem('Images', { routerLink: ['image/search'] }),
new NavbarItem('Video', { routerLink: ['video/search'] }),
]})
];
}HTML:
<nav class="navbar navbar-default" *ngIf="shown">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" routerLink="/">Content</a>
</div>
<ul class="nav navbar-nav" [navbarItems]="navigationItems"></ul>
<ul class="nav navbar-nav navbar-right" [navbarItems]="navigationItems-right"></ul>
</div>
</nav>So the actual question is: is it possible to build this functionality as another ng2-bootstrap module?
This could also cover the #540