Skip to content

Commit

Permalink
fix(module): use window reference via DI
Browse files Browse the repository at this point in the history
So it does not break SSR

closes #186
  • Loading branch information
gund committed Oct 14, 2018
1 parent 5f73689 commit 1c05874
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/dynamic/dynamic-directives.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
DynamicDirectivesDirective,
} from './dynamic-directives.directive';
import { IoFactoryService } from './io-factory.service';
import { WindowRefService, WINDOW_REF } from './window-ref.service';

const getComponentInjectorFrom = getDirective(ComponentInjectorComponent);
const getInjectedComponentFrom = getDirective(InjectedComponent);
Expand Down Expand Up @@ -101,6 +102,8 @@ describe('Directive: DynamicDirectives', () => {
],
providers: [
{ provide: COMPONENT_INJECTOR, useValue: ComponentInjectorComponent },
{ provide: WINDOW_REF, useValue: window },
WindowRefService,
IoFactoryService,
],
});
Expand Down
8 changes: 7 additions & 1 deletion src/dynamic/dynamic-directives.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ComponentOutletInjectorDirective } from './component-outlet-injector.di
import { IoFactoryService } from './io-factory.service';
import { InputsType, IoService, OutputsType } from './io.service';
import { getCtorType } from './util';
import { WindowRefService } from './window-ref.service';

export interface DynamicDirectiveDef<T> {
type: Type<T>;
Expand Down Expand Up @@ -88,6 +89,10 @@ export class DynamicDirectivesDirective implements OnDestroy, DoCheck {
return this.componentRef['_viewRef']['_viewContainerRef'];
}

private get reflect() {
return (this.windowRef.nativeWindow as any).Reflect;
}

private dirRef = new Map<Type<any>, DirectiveRef<any>>();
private dirIo = new Map<Type<any>, IoService>();
private dirsDiffer = this.iterableDiffers
Expand All @@ -98,6 +103,7 @@ export class DynamicDirectivesDirective implements OnDestroy, DoCheck {
private injector: Injector,
private iterableDiffers: IterableDiffers,
private ioFactoryService: IoFactoryService,
private windowRef: WindowRefService,
@Inject(COMPONENT_INJECTOR)
private componentInjectorType: ComponentInjector,
@Host()
Expand Down Expand Up @@ -208,7 +214,7 @@ export class DynamicDirectivesDirective implements OnDestroy, DoCheck {
}

private createDirective<T>(dirType: Type<T>): T {
const ctorParams: any[] = getCtorType(dirType);
const ctorParams: any[] = getCtorType(dirType, this.reflect);
const resolvedParams = ctorParams.map(p => this.resolveDep(p));
return new dirType(...resolvedParams);
}
Expand Down
7 changes: 7 additions & 0 deletions src/dynamic/dynamic.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { DynamicDirectivesDirective } from './dynamic-directives.directive';
import { DynamicComponent } from './dynamic.component';
import { DynamicDirective } from './dynamic.directive';
import { IoFactoryService } from './io-factory.service';
import { WindowRefService, WINDOW_REF } from './window-ref.service';

export function windowRefFactory() {
return window;
}

@NgModule({
imports: [CommonModule],
Expand Down Expand Up @@ -46,6 +51,8 @@ export class DynamicModule {
},
{ provide: COMPONENT_INJECTOR, useValue: componentInjector },
IoFactoryService,
{ provide: WINDOW_REF, useFactory: windowRefFactory },
WindowRefService,
],
};
}
Expand Down
9 changes: 5 additions & 4 deletions src/dynamic/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import {
SimpleChanges,
} from '@angular/core';

const { Reflect } = window as any;

export type KeyValueChangeRecordAny = KeyValueChangeRecord<any, any>;

export function createNewChange(val: any): SimpleChange {
Expand Down Expand Up @@ -61,6 +59,9 @@ export function changesFromRecord(opts: DefaultOpts = defaultOpts) {

export function noop(): void {}

export function getCtorType(ctor: any): any[] {
return Reflect.getMetadata('design:paramtypes', ctor);
export function getCtorType(
ctor: any,
reflect: { getMetadata: Function },
): any[] {
return reflect.getMetadata('design:paramtypes', ctor);
}
28 changes: 28 additions & 0 deletions src/dynamic/window-ref.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* tslint:disable:no-unused-variable */

import { TestBed, async, inject } from '@angular/core/testing';
import { WindowRefService, WINDOW_REF } from './window-ref.service';

describe('Service: WindowRef', () => {
let service: WindowRefService;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
WindowRefService,
{ provide: WINDOW_REF, useValue: 'my-window' },
],
});
service = TestBed.get(WindowRefService);
});

it('should have `` prop', () => {
expect(service.nativeWindow).toBeDefined();
});

describe('`nativeWindow` prop', () => {
it('should be the value from DI token `WINDOW_REF`', () => {
expect(service.nativeWindow).toBe('my-window');
});
});
});
10 changes: 10 additions & 0 deletions src/dynamic/window-ref.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Injectable, InjectionToken, Injector } from '@angular/core';

export const WINDOW_REF = new InjectionToken<Window>('WindowRef');

@Injectable()
export class WindowRefService {
nativeWindow = this.injector.get(WINDOW_REF, null);

constructor(private injector: Injector) {}
}

0 comments on commit 1c05874

Please sign in to comment.