Skip to content

Commit

Permalink
feat(module): add additional configuration using forRoot and forFeature
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammedzamakhan committed Sep 17, 2019
1 parent 8382ac8 commit afdaec7
Show file tree
Hide file tree
Showing 23 changed files with 315 additions and 34 deletions.
7 changes: 6 additions & 1 deletion projects/elements-demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
import { RootErrorComponent } from './shared/root-error/root-error.component';

@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
Expand All @@ -25,7 +26,11 @@ import { environment } from '../environments/environment';
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production
}),
LazyElementsModule,
LazyElementsModule.forRoot({
rootOptions: {
errorComponent: RootErrorComponent
}
}),

// local
CoreModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ <h2>Elements configured in module with HTML inline options</h2>
</p>
<pre [highlight]="codeExample2html"></pre>
<pre [highlight]="codeExample2module"></pre>
<pre [highlight]="codeExample2coreModule"></pre>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class AdvancedComponent implements OnInit {
codeExample1module = CODE_EXAMPLE_1_MODULE;
codeExample1html = CODE_EXAMPLE_1_HTML;
codeExample2module = CODE_EXAMPLE_2_MODULE;
codeExample2coreModule = CODE_EXAMPLE_2_CORE_MODULE;
codeExample2html = CODE_EXAMPLE_2_HTML;
codeExample3module = CODE_EXAMPLE_3_MODULE;
codeExample3html = CODE_EXAMPLE_3_HTML;
Expand All @@ -34,7 +35,12 @@ export class AdvancedComponent implements OnInit {
const CODE_EXAMPLE_1_MODULE = `// pre-configured LazyElementsModule
const options: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'ion-button', url: 'https://unpkg.com/@ionic/core@4.6.2/dist/ionic/ionic.js' }
{
tag: 'ion-button',
url: 'https://unpkg.com/@ionic/core@4.6.2/dist/ionic/ionic.js',
loadingComponent: SpinnerComponent,
errorComponent: ErrorComponent
}
]
};
Expand All @@ -51,10 +57,13 @@ export class FeatureModule { }
const CODE_EXAMPLE_1_HTML = `<!-- No need to specify url -->
<ion-button *axLazyElement></ion-button>`;

const CODE_EXAMPLE_2_MODULE = `// pre-configured LazyElementsModule
const CODE_EXAMPLE_2_MODULE = `// pre-configured LazyElementsModule in FeatureModule
const options: LazyElementModuleOptions = {
elementConfigs: [
{ tag: 'mwc-checkbox', url: 'https://unpkg.com/@material/mwc-checkbox@0.6.0/mwc-checkbox.js?module' }
{
tag: 'mwc-checkbox',
url: 'https://unpkg.com/@material/mwc-checkbox@0.6.0/mwc-checkbox.js?module'
}
]
};
Expand All @@ -68,6 +77,22 @@ const options: LazyElementModuleOptions = {
export class FeatureModule { }
`;

const CODE_EXAMPLE_2_CORE_MODULE = `// pre-configured LazyElementsModule in CoreModule or AppModule
const options: LazyElementModuleRootOptions = {
rootOptions: {
errorComponent: RootErrorComponent
}
};
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [
LazyElementsModule.forRoot(options),
]
})
export class CoreModule { }
`;

const CODE_EXAMPLE_2_HTML = `<!-- We have to specify null; url to be able to pass in additional options -->
<mwc-checkbox *axLazyElement="null; module: true; loadingTemplate: loading;"></mwc-checkbox>`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ import { SharedModule } from '../../../shared/shared.module';

import { AdvancedRoutingModule } from './advanced-routing.module';
import { AdvancedComponent } from './advanced.component';
import { SpinnerComponent } from '../../../shared/spinner/spinner.component';
import { ErrorComponent } from '../../../shared/error/error.component';

const options: LazyElementModuleOptions = {
elementConfigs: [
{
tag: 'ion-button',
url: 'https://unpkg.com/@ionic/core@4.6.2/dist/ionic/ionic.js'
url: 'https://unpkg.com/@ionic/core@4.6.2/dist/ionic/ionic.js',
loadingComponent: SpinnerComponent,
errorComponent: ErrorComponent
},
{
tag: 'mwc-switch',
Expand All @@ -25,7 +29,8 @@ const options: LazyElementModuleOptions = {
{
tag: 'mwc-checkbox',
url:
'https://unpkg.com/@material/mwc-checkbox@0.6.0/mwc-checkbox.js?module'
'https://unpkg.com/@material/mwc-checkbox@0.6.0/mwc-checkbox.js?module',
isModule: true
}
]
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>Loading failed ⚠️...</p>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ErrorComponent } from './error.component';

describe('ErrorComponent', () => {
let component: ErrorComponent;
let fixture: ComponentFixture<ErrorComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ErrorComponent]
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(ErrorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
12 changes: 12 additions & 0 deletions projects/elements-demo/src/app/shared/error/error.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'demo-error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.scss']
})
export class ErrorComponent implements OnInit {
constructor() {}

ngOnInit() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>root loading error...</p>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { RootErrorComponent } from './root-error.component';

describe('RootErrorComponent', () => {
let component: RootErrorComponent;
let fixture: ComponentFixture<RootErrorComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [RootErrorComponent]
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(RootErrorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'demo-root-error',
templateUrl: './root-error.component.html',
styleUrls: ['./root-error.component.scss']
})
export class RootErrorComponent implements OnInit {
constructor() {}

ngOnInit() {}
}
7 changes: 5 additions & 2 deletions projects/elements-demo/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import {
MatExpansionModule,
MatSnackBarModule
} from '@angular/material';
import { SpinnerComponent } from './spinner/spinner.component';
import { ErrorComponent } from './error/error.component';
import { RootErrorComponent } from './root-error/root-error.component';

const ANGULAR_MATERIAL_MODULES = [
MatCardModule,
Expand All @@ -29,9 +32,9 @@ const ANGULAR_MATERIAL_MODULES = [
];

@NgModule({
declarations: [],
declarations: [SpinnerComponent, ErrorComponent, RootErrorComponent],
imports: [CommonModule, ...ANGULAR_MATERIAL_MODULES],
exports: [CommonModule, ...ANGULAR_MATERIAL_MODULES]
exports: [CommonModule, ...ANGULAR_MATERIAL_MODULES, SpinnerComponent]
})
export class SharedModule {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>spinning...</p>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SpinnerComponent } from './spinner.component';

describe('SpinnerComponent', () => {
let component: SpinnerComponent;
let fixture: ComponentFixture<SpinnerComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SpinnerComponent]
}).compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(SpinnerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
12 changes: 12 additions & 0 deletions projects/elements-demo/src/app/shared/spinner/spinner.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'demo-spinner',
templateUrl: './spinner.component.html',
styleUrls: ['./spinner.component.scss']
})
export class SpinnerComponent implements OnInit {
constructor() {}

ngOnInit() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import {
Input,
OnInit,
TemplateRef,
ViewContainerRef
ViewContainerRef,
ComponentFactoryResolver
} from '@angular/core';

import { LazyElementsLoaderService } from '../lazy-elements-loader.service';
import {
LazyElementsLoaderService,
ElementConfig
} from '../lazy-elements-loader.service';

const LOG_PREFIX = '@angular-extensions/elements';

Expand All @@ -27,7 +31,8 @@ export class LazyElementDynamicDirective implements OnInit {
constructor(
private vcr: ViewContainerRef,
private template: TemplateRef<any>,
private elementsLoaderService: LazyElementsLoaderService
private elementsLoaderService: LazyElementsLoaderService,
private cfr: ComponentFactoryResolver
) {}

ngOnInit() {
Expand All @@ -40,8 +45,18 @@ export class LazyElementDynamicDirective implements OnInit {
const host = (this.template as any)._def.element.template.nodes[0].element;
host.name = this.tag;

const elementConfig =
this.elementsLoaderService.getElementConfig(this.tag) ||
({} as ElementConfig);
const options = this.elementsLoaderService.options;
const loadingComponent =
elementConfig.loadingComponent || options.loadingComponent;

if (this.loadingTemplateRef) {
this.vcr.createEmbeddedView(this.loadingTemplateRef);
} else if (loadingComponent) {
const factory = this.cfr.resolveComponentFactory(loadingComponent);
this.vcr.createComponent(factory);
}

this.elementsLoaderService
Expand All @@ -51,9 +66,14 @@ export class LazyElementDynamicDirective implements OnInit {
this.vcr.createEmbeddedView(this.template);
})
.catch(() => {
const errorComponent =
elementConfig.errorComponent || options.errorComponent;
this.vcr.clear();
if (this.errorTemplateRef) {
this.vcr.createEmbeddedView(this.errorTemplateRef);
} else if (errorComponent) {
const factory = this.cfr.resolveComponentFactory(errorComponent);
this.vcr.createComponent(factory);
} else {
console.error(
`${LOG_PREFIX} - Loading of element <${this.tag}> failed, please provide <ng-template #error>Loading failed...</ng-template> and reference it in *axLazyElementDynamic="errorTemplate: error" to display customized error message in place of element`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { Component, CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { LazyElementDirective } from './lazy-element.directive';
import { LazyElementsModule } from '../lazy-elements.module';

@Component({
template: `
<p class="loading">Spinner...</p>
`
})
class SpinnerTestComponent {}

@NgModule({
declarations: [SpinnerTestComponent],
entryComponents: [SpinnerTestComponent]
})
class TestModule {}

@Component({
template: `
Expand Down Expand Up @@ -49,6 +62,9 @@ import { LazyElementDirective } from './lazy-element.directive';
*axLazyElement="'http://elements.com/some-element-module'; module: true"
></some-element>
</div>
<div *ngIf="useElementConfig">
<some-configured-element *axLazyElement></some-configured-element>
</div>
`
})
class TestHostComponent {
Expand All @@ -57,6 +73,7 @@ class TestHostComponent {
useLoadingTemplate = false;
useErrorTemplate = false;
useModule = false;
useElementConfig = false;
}

describe('LazyElementDirective', () => {
Expand All @@ -66,8 +83,20 @@ describe('LazyElementDirective', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
TestModule,
LazyElementsModule.forRoot({
elementConfigs: [
{
tag: 'some-configured-element',
url: 'http://elements.com/some-configured-element-module',
loadingComponent: SpinnerTestComponent
}
]
})
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [TestHostComponent, LazyElementDirective]
declarations: [TestHostComponent]
}).compileComponents();
}));

Expand Down Expand Up @@ -186,4 +215,11 @@ describe('LazyElementDirective', () => {
);
expect(appendChildSpy.calls.argsFor(1)[0].type).toBe('module');
});

it('uses elementConfig for the tag', () => {
testHostComponent.useElementConfig = true;
fixture.detectChanges();

expect(document.querySelector('.loading').textContent).toBe('Spinner...');
});
});

0 comments on commit afdaec7

Please sign in to comment.