refactor(core): remove deprecated @Component.directives and @Component.pipes

BREAKING CHANGE: previously deprecated @Component.directives and @Component.pipes support was removed.

All the components and pipes now must be declarated via an NgModule. NgModule is the basic
compilation block passed into the Angular compiler via Compiler#compileModuleSync or #compileModuleAsync.

Because of this change, the Compiler#compileComponentAsync and #compileComponentSync were removed as well -
any code doing compilation should compile module instead using the apis mentioned above.

Lastly, since modules are the basic compilation unit, the ngUpgrade module was modified to always require
an NgModule to be passed into the UpgradeAdapter's constructor - previously this was optional.
This commit is contained in:
Igor Minar
2016-08-19 13:51:45 -07:00
parent a782232ca3
commit 4a740f23a4
18 changed files with 389 additions and 665 deletions

View File

@ -410,7 +410,7 @@ export class CompileTemplateMetadata {
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, providers,
viewProviders, queries, viewQueries, entryComponents, viewDirectives, viewPipes, template}: {
viewProviders, queries, viewQueries, entryComponents, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
@ -479,8 +479,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
queries,
viewQueries,
entryComponents,
viewDirectives,
viewPipes,
template,
});
}
@ -500,17 +498,13 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
viewQueries: CompileQueryMetadata[];
// Note: Need to keep types here to prevent cycles!
entryComponents: CompileTypeMetadata[];
// Note: Need to keep types here to prevent cycles!
viewDirectives: CompileTypeMetadata[];
// Note: Need to keep types here to prevent cycles!
viewPipes: CompileTypeMetadata[];
template: CompileTemplateMetadata;
constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners,
hostProperties, hostAttributes, providers, viewProviders, queries, viewQueries,
entryComponents, viewDirectives, viewPipes, template}: {
entryComponents, template}: {
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
@ -547,8 +541,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
this.queries = _normalizeArray(queries);
this.viewQueries = _normalizeArray(viewQueries);
this.entryComponents = _normalizeArray(entryComponents);
this.viewDirectives = _normalizeArray(viewDirectives);
this.viewPipes = _normalizeArray(viewPipes);
this.template = template;
}

View File

@ -142,8 +142,6 @@ export class DirectiveResolver {
providers: dm.providers,
viewProviders: dm.viewProviders,
entryComponents: dm.entryComponents,
directives: dm.directives,
pipes: dm.pipes,
template: dm.template,
templateUrl: dm.templateUrl,
styles: dm.styles,

View File

@ -8,12 +8,11 @@
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, AttributeMetadata, ChangeDetectionStrategy, ComponentMetadata, HostMetadata, InjectMetadata, Injectable, ModuleWithProviders, OptionalMetadata, Provider, QueryMetadata, SchemaMetadata, SelfMetadata, SkipSelfMetadata, Type, ViewQueryMetadata, resolveForwardRef} from '@angular/core';
import {Console, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private';
import {LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from '../core_private';
import {StringMapWrapper} from '../src/facade/collection';
import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
import * as cpl from './compile_metadata';
import {CompilerConfig} from './config';
import {DirectiveResolver} from './directive_resolver';
import {BaseException} from './facade/exceptions';
import {isArray, isBlank, isPresent, isString, stringify} from './facade/lang';
@ -36,8 +35,7 @@ export class CompileMetadataResolver {
constructor(
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
private _pipeResolver: PipeResolver, private _config: CompilerConfig,
private _console: Console, private _schemaRegistry: ElementSchemaRegistry,
private _pipeResolver: PipeResolver, private _schemaRegistry: ElementSchemaRegistry,
private _reflector: ReflectorReader = reflector) {}
private sanitizeTokenName(token: any): string {
@ -124,9 +122,7 @@ export class CompileMetadataResolver {
var changeDetectionStrategy: ChangeDetectionStrategy = null;
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
var moduleUrl = staticTypeModuleUrl(directiveType);
var viewDirectiveTypes: cpl.CompileTypeMetadata[] = [];
var viewPipeTypes: cpl.CompileTypeMetadata[] = [];
var entryComponentTypes: cpl.CompileTypeMetadata[] = [];
var entryComponentMetadata: cpl.CompileTypeMetadata[] = [];
let selector = dirMeta.selector;
if (dirMeta instanceof ComponentMetadata) {
var cmpMeta = <ComponentMetadata>dirMeta;
@ -150,32 +146,15 @@ export class CompileMetadataResolver {
changeDetectionStrategy = cmpMeta.changeDetection;
if (isPresent(dirMeta.viewProviders)) {
viewProviders = this.getProvidersMetadata(
verifyNonBlankProviders(directiveType, dirMeta.viewProviders, 'viewProviders'), []);
verifyNonBlankProviders(directiveType, dirMeta.viewProviders, 'viewProviders'),
entryComponentMetadata);
}
moduleUrl = componentModuleUrl(this._reflector, directiveType, cmpMeta);
if (cmpMeta.entryComponents) {
entryComponentTypes =
entryComponentMetadata =
flattenArray(cmpMeta.entryComponents)
.map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type)));
}
if (cmpMeta.directives) {
viewDirectiveTypes = flattenArray(cmpMeta.directives).map((type) => {
if (!type) {
throw new BaseException(
`Unexpected directive value '${type}' on the View of component '${stringify(directiveType)}'`);
}
return this.getTypeMetadata(type, staticTypeModuleUrl(type));
});
}
if (cmpMeta.pipes) {
viewPipeTypes = flattenArray(cmpMeta.pipes).map((type) => {
if (!type) {
throw new BaseException(
`Unexpected pipe value '${type}' on the View of component '${stringify(directiveType)}'`);
}
return this.getTypeMetadata(type, staticTypeModuleUrl(type));
});
.map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type)))
.concat(entryComponentMetadata);
}
if (!selector) {
selector = this._schemaRegistry.getDefaultComponentElementName();
@ -191,7 +170,7 @@ export class CompileMetadataResolver {
if (isPresent(dirMeta.providers)) {
providers = this.getProvidersMetadata(
verifyNonBlankProviders(directiveType, dirMeta.providers, 'providers'),
entryComponentTypes);
entryComponentMetadata);
}
var queries: cpl.CompileQueryMetadata[] = [];
var viewQueries: cpl.CompileQueryMetadata[] = [];
@ -213,9 +192,7 @@ export class CompileMetadataResolver {
viewProviders: viewProviders,
queries: queries,
viewQueries: viewQueries,
viewDirectives: viewDirectiveTypes,
viewPipes: viewPipeTypes,
entryComponents: entryComponentTypes
entryComponents: entryComponentMetadata
});
this._directiveCache.set(directiveType, meta);
}
@ -359,19 +336,6 @@ export class CompileMetadataResolver {
return compileMeta;
}
addComponentToModule(moduleType: Type<any>, compType: Type<any>) {
const moduleMeta = this.getNgModuleMetadata(moduleType);
// Collect @Component.directives/pipes/entryComponents into our declared directives/pipes.
const compMeta = this.getDirectiveMetadata(compType, false);
this._addDirectiveToModule(
compMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
moduleMeta.declaredDirectives);
moduleMeta.transitiveModule.entryComponents.push(compMeta.type);
moduleMeta.entryComponents.push(compMeta.type);
this._verifyModule(moduleMeta);
}
private _verifyModule(moduleMeta: cpl.CompileNgModuleMetadata) {
moduleMeta.exportedDirectives.forEach((dirMeta) => {
@ -386,17 +350,6 @@ export class CompileMetadataResolver {
`Can't export pipe ${stringify(pipeMeta.type.runtime)} from ${stringify(moduleMeta.type.runtime)} as it was neither declared nor imported!`);
}
});
moduleMeta.entryComponents.forEach((entryComponentType) => {
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
throw new BaseException(
`NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported! If ${stringify(entryComponentType.runtime)} is declared in an imported module, make sure it is exported.`);
}
});
// Collect @Component.directives/pipes/entryComponents into our declared
// directives/pipes. Do this last so that directives added by previous steps
// are considered as well!
moduleMeta.declaredDirectives.forEach(
(dirMeta) => { this._getTransitiveViewDirectivesAndPipes(dirMeta, moduleMeta); });
}
private _getTypeDescriptor(type: Type<any>): string {
@ -422,41 +375,6 @@ export class CompileMetadataResolver {
this._ngModuleOfTypes.set(type, moduleType);
}
private _getTransitiveViewDirectivesAndPipes(
compMeta: cpl.CompileDirectiveMetadata, moduleMeta: cpl.CompileNgModuleMetadata) {
if (!compMeta.isComponent) {
return;
}
const addPipe = (pipeType: Type<any>) => {
const pipeMeta = this.getPipeMetadata(pipeType);
this._addPipeToModule(
pipeMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule, moduleMeta.declaredPipes);
};
const addDirective = (dirType: Type<any>) => {
const dirMeta = this.getDirectiveMetadata(dirType);
if (this._addDirectiveToModule(
dirMeta, moduleMeta.type.runtime, moduleMeta.transitiveModule,
moduleMeta.declaredDirectives)) {
this._getTransitiveViewDirectivesAndPipes(dirMeta, moduleMeta);
}
};
if (compMeta.viewPipes) {
compMeta.viewPipes.forEach((cplType) => addPipe(cplType.runtime));
}
if (compMeta.viewDirectives) {
compMeta.viewDirectives.forEach((cplType) => addDirective(cplType.runtime));
}
compMeta.entryComponents.forEach((entryComponentType) => {
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
this._console.warn(
`Component ${stringify(compMeta.type.runtime)} in NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported into the module! This warning will become an error after final.`);
addDirective(entryComponentType.runtime);
}
});
}
private _getTransitiveNgModuleMetadata(
importedModules: cpl.CompileNgModuleMetadata[],
exportedModules: cpl.CompileNgModuleMetadata[]): cpl.TransitiveCompileNgModuleMetadata {

View File

@ -46,8 +46,7 @@ export class RuntimeCompiler implements Compiler {
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
private _templateNormalizer: DirectiveNormalizer, private _templateParser: TemplateParser,
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig,
private _console: Console) {}
private _ngModuleCompiler: NgModuleCompiler, private _compilerConfig: CompilerConfig) {}
get injector(): Injector { return this._injector; }
@ -68,23 +67,6 @@ export class RuntimeCompiler implements Compiler {
return this._compileModuleAndAllComponents(moduleType, false).asyncResult;
}
compileComponentAsync<T>(compType: Type<T>, ngModule: Type<any> = null):
Promise<ComponentFactory<T>> {
if (!ngModule) {
throw new BaseException(
`Calling compileComponentAsync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
}
return this._compileComponentInModule(compType, false, ngModule).asyncResult;
}
compileComponentSync<T>(compType: Type<T>, ngModule: Type<any> = null): ComponentFactory<T> {
if (!ngModule) {
throw new BaseException(
`Calling compileComponentSync on the root compiler without a module is not allowed! (Compiling component ${stringify(compType)})`);
}
return this._compileComponentInModule(compType, true, ngModule).syncResult;
}
private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
SyncAsyncResult<NgModuleFactory<T>> {
const componentPromise = this._compileComponents(moduleType, isSync);
@ -146,17 +128,6 @@ export class RuntimeCompiler implements Compiler {
return ngModuleFactory;
}
private _compileComponentInModule<T>(compType: Type<T>, isSync: boolean, moduleType: Type<any>):
SyncAsyncResult<ComponentFactory<T>> {
this._metadataResolver.addComponentToModule(moduleType, compType);
const componentPromise = this._compileComponents(moduleType, isSync);
const componentFactory: ComponentFactory<T> =
this._assertComponentKnown(compType, true).proxyComponentFactory;
return new SyncAsyncResult(componentFactory, componentPromise.then(() => componentFactory));
}
/**
* @internal
*/
@ -172,10 +143,13 @@ export class RuntimeCompiler implements Compiler {
dirMeta.entryComponents.forEach((entryComponentType) => {
templates.add(this._createCompiledHostTemplate(entryComponentType.runtime));
});
// TODO: what about entryComponents of entryComponents? maybe skip here and just do the
// below?
}
});
localModuleMeta.entryComponents.forEach((entryComponentType) => {
templates.add(this._createCompiledHostTemplate(entryComponentType.runtime));
// TODO: what about entryComponents of entryComponents?
});
});
templates.forEach((template) => {
@ -248,8 +222,13 @@ export class RuntimeCompiler implements Compiler {
const compiledTemplate = isHost ? this._compiledHostTemplateCache.get(compType) :
this._compiledTemplateCache.get(compType);
if (!compiledTemplate) {
throw new BaseException(
`Illegal state: CompiledTemplate for ${stringify(compType)} (isHost: ${isHost}) does not exist!`);
if (isHost) {
throw new BaseException(
`Illegal state: Compiled view for component ${stringify(compType)} does not exist!`);
} else {
throw new BaseException(
`Component ${stringify(compType)} is not part of any NgModule or the module has not been imported into your module.`);
}
}
return compiledTemplate;
}
@ -403,15 +382,6 @@ class ModuleBoundCompiler implements Compiler {
get _injector(): Injector { return this._delegate.injector; }
compileComponentAsync<T>(compType: Type<T>, ngModule: Type<any> = null):
Promise<ComponentFactory<T>> {
return this._delegate.compileComponentAsync(compType, ngModule ? ngModule : this._ngModule);
}
compileComponentSync<T>(compType: Type<T>, ngModule: Type<any> = null): ComponentFactory<T> {
return this._delegate.compileComponentSync(compType, ngModule ? ngModule : this._ngModule);
}
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
return this._delegate.compileModuleSync(moduleType);
}

View File

@ -6,17 +6,21 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Component, ComponentMetadata, Injector} from '@angular/core';
import {beforeEach, ddescribe, describe, expect, iit, inject, it} from '@angular/core/testing/testing_internal';
import {Component, ComponentMetadata, Directive, Injector} from '@angular/core';
import {TestBed, inject} from '@angular/core/testing';
import {ViewMetadata} from '../core_private';
import {isBlank, stringify} from '../src/facade/lang';
import {MockDirectiveResolver} from '../testing';
export function main() {
describe('MockDirectiveResolver', () => {
var dirResolver: MockDirectiveResolver;
beforeEach(() => {
TestBed.configureTestingModule(
{declarations: [SomeDirective, SomeOtherDirective, SomeComponent]});
});
beforeEach(inject([Injector], (injector: Injector) => {
dirResolver = new MockDirectiveResolver(injector);
}));
@ -40,14 +44,12 @@ export function main() {
it('should fallback to the default ViewResolver when templates are not overridden', () => {
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.template).toEqual('template');
expect(view.directives).toEqual([SomeDirective]);
});
it('should allow overriding the @View', () => {
dirResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.template).toEqual('overridden template');
expect(isBlank(view.directives)).toBe(true);
});
it('should allow overriding a view after it has been resolved', () => {
@ -55,7 +57,6 @@ export function main() {
dirResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.template).toEqual('overridden template');
expect(isBlank(view.directives)).toBe(true);
});
});
@ -64,7 +65,6 @@ export function main() {
dirResolver.setInlineTemplate(SomeComponent, 'overridden template');
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.template).toEqual('overridden template');
expect(view.directives).toEqual([SomeDirective]);
});
it('should allow overriding an overridden @View', () => {
@ -81,50 +81,17 @@ export function main() {
expect(view.template).toEqual('overridden template');
});
});
describe('Directive overriding', () => {
it('should allow overriding a directive from the default view', () => {
dirResolver.overrideViewDirective(SomeComponent, SomeDirective, SomeOtherDirective);
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.directives.length).toEqual(1);
expect(view.directives[0]).toBe(SomeOtherDirective);
});
it('should allow overriding a directive from an overridden @View', () => {
dirResolver.setView(SomeComponent, new ViewMetadata({directives: [SomeOtherDirective]}));
dirResolver.overrideViewDirective(SomeComponent, SomeOtherDirective, SomeComponent);
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.directives.length).toEqual(1);
expect(view.directives[0]).toBe(SomeComponent);
});
it('should throw when the overridden directive is not present', () => {
dirResolver.overrideViewDirective(SomeComponent, SomeOtherDirective, SomeDirective);
expect(() => { dirResolver.resolve(SomeComponent); })
.toThrowError(
`Overriden directive ${stringify(SomeOtherDirective)} not found in the template of ${stringify(SomeComponent)}`);
});
it('should allow overriding a directive after its view has been resolved', () => {
dirResolver.resolve(SomeComponent);
dirResolver.overrideViewDirective(SomeComponent, SomeDirective, SomeOtherDirective);
var view = <ComponentMetadata>dirResolver.resolve(SomeComponent);
expect(view.directives.length).toEqual(1);
expect(view.directives[0]).toBe(SomeOtherDirective);
});
});
});
}
class SomeDirective {}
@Directive({selector: 'some-directive'})
class SomeDirective {
}
@Component({
selector: 'cmp',
template: 'template',
directives: [SomeDirective],
})
@Component({selector: 'cmp', template: 'template'})
class SomeComponent {
}
class SomeOtherDirective {}
@Directive({selector: 'some-other-directive'})
class SomeOtherDirective {
}

View File

@ -104,16 +104,7 @@ class SomeDirectiveWithViewChild {
c: any;
}
class SomeDir {}
class SomePipe {}
@Component({
selector: 'sample',
template: 'some template',
directives: [SomeDir],
pipes: [SomePipe],
styles: ['some styles']
})
@Component({selector: 'sample', template: 'some template', styles: ['some styles']})
class ComponentWithTemplate {
}
@ -236,8 +227,6 @@ export function main() {
it('should read out the template related metadata from the Component metadata', () => {
var compMetadata = <ComponentMetadata>resolver.resolve(ComponentWithTemplate);
expect(compMetadata.template).toEqual('some template');
expect(compMetadata.directives).toEqual([SomeDir]);
expect(compMetadata.pipes).toEqual([SomePipe]);
expect(compMetadata.styles).toEqual(['some styles']);
});
});

View File

@ -140,12 +140,12 @@ export function main() {
it('should throw when using a templateUrl in a nested component that has not been compiled before',
() => {
@NgModule({declarations: [SomeComp], entryComponents: [SomeComp]})
@NgModule({declarations: [SomeComp, ChildComp], entryComponents: [SomeComp]})
class SomeModule {
}
resourceLoader.spy('get').andCallFake(() => Promise.resolve(''));
dirResolver.setView(SomeComp, new ViewMetadata({template: '', directives: [ChildComp]}));
dirResolver.setView(SomeComp, new ViewMetadata({template: ''}));
dirResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
expect(() => compiler.compileModuleSync(SomeModule))
.toThrowError(

View File

@ -7,7 +7,6 @@
*/
export * from './testing/schema_registry_mock';
export * from './testing/test_component_builder';
export * from './testing/directive_resolver_mock';
export * from './testing/ng_module_resolver_mock';
export * from './testing/pipe_resolver_mock';
@ -39,13 +38,7 @@ export class TestingCompilerImpl implements TestingCompiler {
private _compiler: RuntimeCompiler, private _directiveResolver: MockDirectiveResolver,
private _pipeResolver: MockPipeResolver, private _moduleResolver: MockNgModuleResolver) {}
get injector(): Injector { return this._compiler.injector; }
compileComponentAsync<T>(component: Type<T>, ngModule: Type<any> = null):
Promise<ComponentFactory<T>> {
return this._compiler.compileComponentAsync(component, <any>ngModule);
}
compileComponentSync<T>(component: Type<T>, ngModule: Type<any> = null): ComponentFactory<T> {
return this._compiler.compileComponentSync(component, <any>ngModule);
}
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
return this._compiler.compileModuleSync(moduleType);
}

View File

@ -11,8 +11,7 @@ import {ViewMetadata} from '../core_private';
import {DirectiveResolver} from '../src/directive_resolver';
import {Map} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions';
import {isArray, isPresent, stringify} from '../src/facade/lang';
import {isArray, isPresent} from '../src/facade/lang';
@ -28,7 +27,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
private _views = new Map<Type<any>, ViewMetadata>();
private _inlineTemplates = new Map<Type<any>, string>();
private _animations = new Map<Type<any>, AnimationEntryMetadata[]>();
private _directiveOverrides = new Map<Type<any>, Map<Type<any>, Type<any>>>();
constructor(private _injector: Injector) { super(); }
@ -67,13 +65,8 @@ export class MockDirectiveResolver extends DirectiveResolver {
view = metadata;
}
const directives: any[] = [];
if (isPresent(view.directives)) {
flattenArray(view.directives, directives);
}
let animations = view.animations;
let templateUrl = view.templateUrl;
const directiveOverrides = this._directiveOverrides.get(type);
const inlineAnimations = this._animations.get(type);
if (isPresent(inlineAnimations)) {
@ -87,17 +80,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
inlineTemplate = view.template;
}
if (isPresent(directiveOverrides) && isPresent(view.directives)) {
directiveOverrides.forEach((to, from) => {
var srcIndex = directives.indexOf(from);
if (srcIndex == -1) {
throw new BaseException(
`Overriden directive ${stringify(from)} not found in the template of ${stringify(type)}`);
}
directives[srcIndex] = to;
});
}
return new ComponentMetadata({
selector: metadata.selector,
inputs: metadata.inputs,
@ -112,11 +94,9 @@ export class MockDirectiveResolver extends DirectiveResolver {
entryComponents: metadata.entryComponents,
template: inlineTemplate,
templateUrl: templateUrl,
directives: directives.length > 0 ? directives : null,
animations: animations,
styles: view.styles,
styleUrls: view.styleUrls,
pipes: view.pipes,
encapsulation: view.encapsulation,
interpolation: view.interpolation
});
@ -170,21 +150,6 @@ export class MockDirectiveResolver extends DirectiveResolver {
this._animations.set(component, animations);
this._clearCacheFor(component);
}
/**
* Overrides a directive from the component {@link ViewMetadata}.
*/
overrideViewDirective(component: Type<any>, from: Type<any>, to: Type<any>): void {
var overrides = this._directiveOverrides.get(component);
if (!overrides) {
overrides = new Map<Type<any>, Type<any>>();
this._directiveOverrides.set(component, overrides);
}
overrides.set(from, to);
this._clearCacheFor(component);
}
}
function flattenArray(tree: any[], out: Array<Type<any>|any[]>): void {