Browse Source

feat: simplify predefined projection strategies

pull/3544/head
Arman Ozak 7 years ago
parent
commit
0bb9d21760
  1. 61
      npm/ng-packs/packages/core/src/lib/strategies/projection.strategy.ts
  2. 49
      npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts

61
npm/ng-packs/packages/core/src/lib/strategies/projection.strategy.ts

@ -8,14 +8,9 @@ import {
Type, Type,
ViewContainerRef, ViewContainerRef,
} from '@angular/core'; } from '@angular/core';
import { InferedInstanceOf } from '../models/utility'; import { InferedContextOf, InferedInstanceOf } from '../models/utility';
import { ContainerStrategy, CONTAINER_STRATEGY } from './container.strategy'; import { ContainerStrategy, CONTAINER_STRATEGY } from './container.strategy';
import { import { ContextStrategy, CONTEXT_STRATEGY } from './context.strategy';
ComponentContextStrategy,
ContextStrategy,
CONTEXT_STRATEGY,
TemplateContextStrategy,
} from './context.strategy';
import { DomStrategy, DOM_STRATEGY } from './dom.strategy'; import { DomStrategy, DOM_STRATEGY } from './dom.strategy';
export abstract class ProjectionStrategy<T = any> { export abstract class ProjectionStrategy<T = any> {
@ -78,14 +73,14 @@ export class RootComponentProjectionStrategy<T extends Type<any>> extends Projec
export class TemplateProjectionStrategy<T extends TemplateRef<any>> extends ProjectionStrategy<T> { export class TemplateProjectionStrategy<T extends TemplateRef<any>> extends ProjectionStrategy<T> {
constructor( constructor(
template: T, templateRef: T,
private containerStrategy: ContainerStrategy, private containerStrategy: ContainerStrategy,
private contextStrategy = CONTEXT_STRATEGY.None(), private contextStrategy = CONTEXT_STRATEGY.None(),
) { ) {
super(template); super(templateRef);
} }
injectContent(injector: Injector) { injectContent() {
this.containerStrategy.prepare(); this.containerStrategy.prepare();
const embeddedViewRef = this.containerStrategy.containerRef.createEmbeddedView( const embeddedViewRef = this.containerStrategy.containerRef.createEmbeddedView(
@ -100,76 +95,76 @@ export class TemplateProjectionStrategy<T extends TemplateRef<any>> extends Proj
} }
export const PROJECTION_STRATEGY = { export const PROJECTION_STRATEGY = {
AppendComponentToBody<T extends Type<unknown>>( AppendComponentToBody<T extends Type<unknown>>(component: T, context?: InferedInstanceOf<T>) {
component: T, return new RootComponentProjectionStrategy<T>(
contextStrategy?: ComponentContextStrategy<T>, component,
) { context && CONTEXT_STRATEGY.Component(context),
return new RootComponentProjectionStrategy<T>(component, contextStrategy); );
}, },
AppendComponentToContainer<T extends Type<unknown>>( AppendComponentToContainer<T extends Type<unknown>>(
component: T, component: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: ComponentContextStrategy<T>, context?: InferedInstanceOf<T>,
) { ) {
return new ComponentProjectionStrategy<T>( return new ComponentProjectionStrategy<T>(
component, component,
CONTAINER_STRATEGY.Append(containerRef), CONTAINER_STRATEGY.Append(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Component(context),
); );
}, },
AppendTemplateToContainer<T extends TemplateRef<unknown>>( AppendTemplateToContainer<T extends TemplateRef<unknown>>(
template: T, templateRef: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: TemplateContextStrategy<T>, context?: InferedContextOf<T>,
) { ) {
return new TemplateProjectionStrategy<T>( return new TemplateProjectionStrategy<T>(
template, templateRef,
CONTAINER_STRATEGY.Append(containerRef), CONTAINER_STRATEGY.Append(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Template(context),
); );
}, },
PrependComponentToContainer<T extends Type<unknown>>( PrependComponentToContainer<T extends Type<unknown>>(
component: T, component: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: ComponentContextStrategy<T>, context?: InferedInstanceOf<T>,
) { ) {
return new ComponentProjectionStrategy<T>( return new ComponentProjectionStrategy<T>(
component, component,
CONTAINER_STRATEGY.Prepend(containerRef), CONTAINER_STRATEGY.Prepend(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Component(context),
); );
}, },
PrependTemplateToContainer<T extends TemplateRef<unknown>>( PrependTemplateToContainer<T extends TemplateRef<unknown>>(
template: T, templateRef: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: TemplateContextStrategy<T>, context?: InferedContextOf<T>,
) { ) {
return new TemplateProjectionStrategy<T>( return new TemplateProjectionStrategy<T>(
template, templateRef,
CONTAINER_STRATEGY.Prepend(containerRef), CONTAINER_STRATEGY.Prepend(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Template(context),
); );
}, },
ProjectComponentToContainer<T extends Type<unknown>>( ProjectComponentToContainer<T extends Type<unknown>>(
component: T, component: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: ComponentContextStrategy<T>, context?: InferedInstanceOf<T>,
) { ) {
return new ComponentProjectionStrategy<T>( return new ComponentProjectionStrategy<T>(
component, component,
CONTAINER_STRATEGY.Clear(containerRef), CONTAINER_STRATEGY.Clear(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Component(context),
); );
}, },
ProjectTemplateToContainer<T extends TemplateRef<unknown>>( ProjectTemplateToContainer<T extends TemplateRef<unknown>>(
template: T, templateRef: T,
containerRef: ViewContainerRef, containerRef: ViewContainerRef,
contextStrategy?: TemplateContextStrategy<T>, context?: InferedContextOf<T>,
) { ) {
return new TemplateProjectionStrategy<T>( return new TemplateProjectionStrategy<T>(
template, templateRef,
CONTAINER_STRATEGY.Clear(containerRef), CONTAINER_STRATEGY.Clear(containerRef),
contextStrategy, context && CONTEXT_STRATEGY.Template(context),
); );
}, },
}; };

49
npm/ng-packs/packages/core/src/lib/tests/projection.strategy.spec.ts

@ -178,7 +178,7 @@ describe('TemplateProjectionStrategy', () => {
it('should should insert content into container and return an EmbeddedViewRef', () => { it('should should insert content into container and return an EmbeddedViewRef', () => {
const templateRef = spectator.component.templateRef; const templateRef = spectator.component.templateRef;
const strategy = new TemplateProjectionStrategy(templateRef, containerStrategy); const strategy = new TemplateProjectionStrategy(templateRef, containerStrategy);
embeddedViewRef = strategy.injectContent(spectator); embeddedViewRef = strategy.injectContent();
spectator.detectChanges(); spectator.detectChanges();
const div = spectator.query('div.foo'); const div = spectator.query('div.foo');
@ -200,7 +200,7 @@ describe('TemplateProjectionStrategy', () => {
containerStrategy, containerStrategy,
contextStrategy, contextStrategy,
); );
embeddedViewRef = strategy.injectContent(spectator); embeddedViewRef = strategy.injectContent();
spectator.detectChanges(); spectator.detectChanges();
const div = spectator.query('div.foo'); const div = spectator.query('div.foo');
@ -213,6 +213,8 @@ describe('TemplateProjectionStrategy', () => {
describe('PROJECTION_STRATEGY', () => { describe('PROJECTION_STRATEGY', () => {
const content = undefined; const content = undefined;
const containerRef = ({ length: 0 } as any) as ViewContainerRef; const containerRef = ({ length: 0 } as any) as ViewContainerRef;
let context = undefined;
test.each` test.each`
name | Strategy | containerStrategy name | Strategy | containerStrategy
${'AppendComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Append} ${'AppendComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Append}
@ -222,23 +224,52 @@ describe('PROJECTION_STRATEGY', () => {
${'ProjectComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Clear} ${'ProjectComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Clear}
${'ProjectTemplateToContainer'} | ${TemplateProjectionStrategy} | ${CONTAINER_STRATEGY.Clear} ${'ProjectTemplateToContainer'} | ${TemplateProjectionStrategy} | ${CONTAINER_STRATEGY.Clear}
`( `(
'should successfully map $name to $Strategy.name with $containerStrategy.name container strategy', 'should successfully map $name to $Strategy.name with $containerStrategy.name container strategy and $contextStrategy.name context strategy',
({ name, Strategy, containerStrategy }) => { ({ name, Strategy, containerStrategy }) => {
expect(PROJECTION_STRATEGY[name](content, containerRef)).toEqual( expect(PROJECTION_STRATEGY[name](content, containerRef, context)).toEqual(
new Strategy(content, containerStrategy(containerRef)), new Strategy(content, containerStrategy(containerRef), CONTEXT_STRATEGY.None()),
); );
}, },
); );
const contextStrategy = undefined;
test.each` test.each`
name | Strategy | domStrategy name | Strategy | domStrategy
${'AppendComponentToBody'} | ${RootComponentProjectionStrategy} | ${DOM_STRATEGY.AppendToBody} ${'AppendComponentToBody'} | ${RootComponentProjectionStrategy} | ${DOM_STRATEGY.AppendToBody}
`( `(
'should successfully map $name to $Strategy.name with $domStrategy.name dom strategy', 'should successfully map $name to $Strategy.name with $domStrategy.name dom strategy',
({ name, Strategy, domStrategy }) => { ({ name, Strategy, domStrategy }) => {
expect(PROJECTION_STRATEGY[name](content, contextStrategy)).toEqual( expect(PROJECTION_STRATEGY[name](content, context)).toEqual(
new Strategy(content, contextStrategy, domStrategy()), new Strategy(content, CONTEXT_STRATEGY.None(), domStrategy()),
);
},
);
test.each`
name | Strategy | containerStrategy | contextStrategy
${'AppendComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Append} | ${CONTEXT_STRATEGY.Component}
${'AppendTemplateToContainer'} | ${TemplateProjectionStrategy} | ${CONTAINER_STRATEGY.Append} | ${CONTEXT_STRATEGY.Template}
${'PrependComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Prepend} | ${CONTEXT_STRATEGY.Component}
${'PrependTemplateToContainer'} | ${TemplateProjectionStrategy} | ${CONTAINER_STRATEGY.Prepend} | ${CONTEXT_STRATEGY.Template}
${'ProjectComponentToContainer'} | ${ComponentProjectionStrategy} | ${CONTAINER_STRATEGY.Clear} | ${CONTEXT_STRATEGY.Component}
${'ProjectTemplateToContainer'} | ${TemplateProjectionStrategy} | ${CONTAINER_STRATEGY.Clear} | ${CONTEXT_STRATEGY.Template}
`(
'should successfully map $name to $Strategy.name with $containerStrategy.name container strategy and $contextStrategy.name context strategy',
({ name, Strategy, containerStrategy, contextStrategy }) => {
context = { x: true };
expect(PROJECTION_STRATEGY[name](content, containerRef, context)).toEqual(
new Strategy(content, containerStrategy(containerRef), contextStrategy(context)),
);
},
);
test.each`
name | Strategy | contextStrategy | domStrategy
${'AppendComponentToBody'} | ${RootComponentProjectionStrategy} | ${CONTEXT_STRATEGY.Component} | ${DOM_STRATEGY.AppendToBody}
`(
'should successfully map $name to $Strategy.name with $contextStrategy.name context strategy and $domStrategy.name dom strategy',
({ name, Strategy, domStrategy, contextStrategy }) => {
context = { x: true };
expect(PROJECTION_STRATEGY[name](content, context)).toEqual(
new Strategy(content, contextStrategy(context), domStrategy()),
); );
}, },
); );

Loading…
Cancel
Save