Skip to content

Instantly share code, notes, and snippets.

@devCrossNet
Last active October 10, 2016 16:09
Show Gist options
  • Save devCrossNet/2ba914a4cc80bf2013fdd691946c54da to your computer and use it in GitHub Desktop.
Save devCrossNet/2ba914a4cc80bf2013fdd691946c54da to your computer and use it in GitHub Desktop.
Content-Outlet for Angular 2 Applications. Change multiple components with the help of routing
./src/app/app.component.html
<md-sidenav-layout>
<md-toolbar color="primary">
<span>
Brand
</span>
<app-content-outlet [id]="'topnav'"></app-content-outlet>
<button md-icon-button (click)="sidenav.toggle()">
<md-icon>menu</md-icon>
</button>
</md-toolbar>
<md-sidenav align="start" mode="over" #sidenav>
<app-content-outlet [id]="'sidebar'"></app-content-outlet>
</md-sidenav>
<div class="app-container">
<router-outlet></router-outlet>
</div>
</md-sidenav-layout>
./src/app/content-outlet/content-outlet-config.ts
export interface IContentOutlet {
path: string;
outlet: string;
component: any;
module: any;
parameters: Object;
}
export class ContentOutletConfig {
items: IContentOutlet[]
}
./src/app/content-outlet/content-outlet.component.ts
import {
Component,
OnInit,
Input,
ViewChild,
ViewContainerRef,
Injector,
Compiler,
ReflectiveInjector
} from '@angular/core';
import { ContentOutletService } from './content-outlet.service';
@Component({
selector: 'content-outlet-placeholder',
template: ''
})
export class ContentOutletPlaceholderComponent {
}
@Component({
selector: 'content-outlet',
template: '<content-outlet-placeholder></content-outlet-placeholder>'
})
export class ContentOutletComponent implements OnInit {
@Input()
private id: string = '';
@ViewChild(ContentOutletPlaceholderComponent, { read: ViewContainerRef })
private viewContainerRef;
constructor(private service: ContentOutletService, private injector: Injector, private compiler: Compiler) {
}
ngOnInit() {
this.service.registerInstance(this.id, this);
}
render(module: any, component: any, parameters?: Object): void {
this.compiler.compileModuleAndAllComponentsAsync(module)
.then(factory => {
let componentFactory = factory.componentFactories
.filter(item => item.componentType === component)[0];
const childInjector = ReflectiveInjector
.resolveAndCreate([], this.injector);
let componentRef = this.viewContainerRef
.createComponent(componentFactory, 0, childInjector);
Object.assign(componentRef.instance, parameters);
});
}
clear(): void {
this.viewContainerRef.clear();
}
}
./src/app/content-outlet/content-outlet.module.ts
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ContentOutletComponent, ContentOutletPlaceholderComponent } from './content-outlet.component';
import { ContentOutletService } from './content-outlet.service';
import { ContentOutletConfig } from './content-outlet-config';
@NgModule({
imports: [
CommonModule
],
declarations: [ContentOutletComponent, ContentOutletPlaceholderComponent],
exports: [ContentOutletComponent],
providers: [ContentOutletService]
})
export class ContentOutletModule {
static _cfg: ContentOutletConfig = { items: [] };
static forRoot(config: ContentOutletConfig): ModuleWithProviders {
this._cfg.items = this._cfg.items.concat(config.items);
return {
ngModule: ContentOutletModule,
providers: [
{ provide: ContentOutletConfig, useValue: this._cfg }
]
};
}
static forChild(config: ContentOutletConfig): ModuleWithProviders {
this._cfg.items = this._cfg.items.concat(config.items);
return {
ngModule: ContentOutletModule,
providers: [
{ provide: ContentOutletConfig, useValue: this._cfg }
]
};
}
}
./src/app/content-outlet/content-outlet.service.ts
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ContentOutletComponent, ContentOutletPlaceholderComponent } from './content-outlet.component';
import { ContentOutletService } from './content-outlet.service';
import { ContentOutletConfig } from './content-outlet-config';
@NgModule({
imports: [
CommonModule
],
declarations: [ContentOutletComponent, ContentOutletPlaceholderComponent],
exports: [ContentOutletComponent],
providers: [ContentOutletService]
})
export class ContentOutletModule {
static forRoot(config: ContentOutletConfig): ModuleWithProviders {
return {
ngModule: ContentOutletModule,
providers: [
{provide: ContentOutletConfig, useValue: config }
]
};
}
}
./src/app/dashboard/dashboard-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ContentOutletService } from '../content-outlet/content-outlet.service';
import { SubComponentOne } from './training-select/sub-component-one.component';
import { SubComponentTwo } from '../content-outlet/sub-component-two.component';
const routes: Routes = [
{
path: 'dashboard',
resolve: {
sidebarLoaded: ContentOutletService
},
children: [
{
path: 'sub',
children: [
{ path: 'component/one', component: SubComponentOne },
{ path: 'component/two', component: SubComponentTwo },
]
},
],
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [ContentOutletService]
})
export class DashboardRoutingModule {
}
./src/app/dashboard/dashboard-routing.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MaterialModule } from '@angular/material';
import { DashboardRoutingModule } from './dashboard-routing.module';
import { ContentOutletModule } from '../content-outlet/content-outlet.module';
import { SidebarComponent } from './sidebar/sidebar.component';
import { TopNavComponent } from './top-nav/top-nav.component';
import { SubComponentOne } from './training-select/sub-component-one.component';
import { SubComponentTwo } from '../content-outlet/sub-component-two.component';
@NgModule({
imports: [
CommonModule,
MaterialModule.forRoot(),
DashboardRoutingModule,
ContentOutletModule.forRoot({
items:[
{
path: 'dashboard',
outlet: 'sidebar',
component: SidebarComponent,
module: DashboardModule,
parameters: {}
},
{
path: 'dashboard',
outlet: 'topnav',
component: TopNavComponent,
module: DashboardModule,
parameters: {}
}
]
})
],
declarations: [SubComponentOne, SubComponentTwo, SidebarComponent, TopNavComponent],
providers: []
})
export class DashboardModule { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment