Skip to content

Instantly share code, notes, and snippets.

@gioragutt
Last active August 19, 2019 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gioragutt/74c5f0fb6a7d54489fa9144372f7b1be to your computer and use it in GitHub Desktop.
Save gioragutt/74c5f0fb6a7d54489fa9144372f7b1be to your computer and use it in GitHub Desktop.
Feature Loading
<ul>
<li *ngFor="let item of formEntries$ | async | keyvalue">
{{item.key}}
<ul>
<li *ngFor="let entry of item.value" (click)="pickedComponent = entry.component">
{{entry.name}}
</li>
</ul>
</li>
</ul>
<button (click)="pickedComponent = null">Clear</button>
<div [class.loaded]="c.loaded">
<ng-template [appFormRepsitoryComponent]="pickedComponent" #c="appFormRepsitoryComponent">
</ng-template>
</div>
import { Component, TemplateRef, Type } from '@angular/core';
import { BootstrapperService, FormsRepository } from 'projects/lazy-feature';
import { Observable, OperatorFunction } from 'rxjs';
import { map } from 'rxjs/operators';
function groupBy<T, K>(keySelector: (t: T) => K): OperatorFunction<T[], Record<any, T[]>> {
return (source: Observable<T[]>) => source.pipe(
map((values: T[]) => {
return values.reduce((acc, v) => {
const key = keySelector(v);
if (!acc[key]) {
acc[key] = [];
}
acc[key] = acc[key] ? [...acc[key], v] : [v];
return acc;
}, {} as any);
}));
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'lazy-loading-modules';
formEntries$ = this.formsRepo.formEntries$().pipe(
groupBy(f => f.category),
);
pickedComponent: Type<any>;
constructor(boostrapperService: BootstrapperService, private formsRepo: FormsRepository) {
boostrapperService.boostrap().subscribe(feature => {
console.log(`Feature ${feature.feature.name} loaded`);
});
}
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LazyFeatureModule, LazyFeatures } from 'projects/lazy-feature';
import { Feature3Module } from './feature3/feature3.module';
import { FormRepositoryComponentDirective } from './form-repository-component.directive';
const features: LazyFeatures = [
{
module: () => import('./feature1/feature1.module').then(m => m.Feature1Module),
name: 'feature1',
// canActivate: ['returnFalse'],
},
{
module: () => import('./feature2/feature2.module').then(m => m.Feature2Module),
name: 'feature2',
}
];
@NgModule({
declarations: [
AppComponent,
FormRepositoryComponentDirective,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
LazyFeatureModule.forRoot(features),
],
providers: [{
provide: 'returnFalse',
useValue: () => false,
}],
bootstrap: [AppComponent]
})
export class AppModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Feature1FormComponent } from './feature1-form/feature1-form.component';
import { LazyFeatureConfig, LazyFeatureModule } from 'projects/Lazy-feature';
const featureModuleConfig: LazyFeatureConfig = {
forms: [
{
category: 'Category 1',
component: Feature1FormComponent,
name: 'Feature1FormComponent',
}
],
};
@NgModule({
declarations: [Feature1FormComponent],
imports: [
CommonModule,
LazyFeatureModule.forFeature(featureModuleConfig)
],
entryComponents: [Feature1FormComponent],
})
export class Feature1Module { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Feature2PageComponent } from './feature2-page/feature2-page.component';
import { LazyFeatureConfig, LazyFeatureModule } from 'projects/Lazy-feature';
const featureModuleConfig: LazyFeatureConfig = {
forms: [
{
category: 'Category 1',
component: Feature2PageComponent,
name: 'Feature2PageComponent',
},
{
category: 'Category 2',
component: Feature2PageComponent,
name: 'Feature2PageComponent Copy ',
},
],
};
@NgModule({
declarations: [Feature2PageComponent],
imports: [
CommonModule,
LazyFeatureModule.forFeature(featureModuleConfig),
],
entryComponents: [Feature2PageComponent],
})
export class Feature2Module { }
import { Directive, Input, Type, ViewContainerRef } from '@angular/core';
import { FormsRepository } from 'projects/lazy-feature';
@Directive({
selector: '[appFormRepsitoryComponent]',
exportAs: 'appFormRepsitoryComponent',
})
export class FormRepositoryComponentDirective<T> {
@Input() set appFormRepsitoryComponent(c: Type<T>) {
this.createComponent(c);
}
get loaded(): boolean {
return this.container.length > 0;
}
constructor(
private container: ViewContainerRef,
private formsRepository: FormsRepository
) { }
createComponent(content: Type<any>): void {
this.container.clear();
if (content) {
const cf = this.formsRepository.resolveComponentFactory(content);
this.container.createComponent(cf);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment