refactor(core): collect lifecycle hooks for all injectable classes

This commit is contained in:
Tobias Bosch 2016-08-02 01:12:24 -07:00
parent 16cc9b46aa
commit ff3b71f7b3
9 changed files with 32 additions and 36 deletions

View File

@ -305,19 +305,22 @@ export class CompileIdentifierMap<KEY extends CompileMetadataWithIdentifier, VAL
export class CompileTypeMetadata extends CompileIdentifierMetadata { export class CompileTypeMetadata extends CompileIdentifierMetadata {
isHost: boolean; isHost: boolean;
diDeps: CompileDiDependencyMetadata[]; diDeps: CompileDiDependencyMetadata[];
lifecycleHooks: LifecycleHooks[];
constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps}: { constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps, lifecycleHooks}: {
runtime?: Type, runtime?: Type,
name?: string, name?: string,
moduleUrl?: string, moduleUrl?: string,
prefix?: string, prefix?: string,
isHost?: boolean, isHost?: boolean,
value?: any, value?: any,
diDeps?: CompileDiDependencyMetadata[] diDeps?: CompileDiDependencyMetadata[],
lifecycleHooks?: LifecycleHooks[];
} = {}) { } = {}) {
super({runtime: runtime, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value}); super({runtime: runtime, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value});
this.isHost = normalizeBool(isHost); this.isHost = normalizeBool(isHost);
this.diDeps = _normalizeArray(diDeps); this.diDeps = _normalizeArray(diDeps);
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
} }
} }
@ -405,9 +408,8 @@ export class CompileTemplateMetadata {
*/ */
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier { export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
static create( static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, {type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, providers,
lifecycleHooks, providers, viewProviders, queries, viewQueries, entryComponents, viewProviders, queries, viewQueries, entryComponents, viewDirectives, viewPipes, template}: {
viewDirectives, viewPipes, template}: {
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
isComponent?: boolean, isComponent?: boolean,
selector?: string, selector?: string,
@ -416,7 +418,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
inputs?: string[], inputs?: string[],
outputs?: string[], outputs?: string[],
host?: {[key: string]: string}, host?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?: providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>, Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewProviders?: viewProviders?:
@ -468,8 +469,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
type, type,
isComponent: normalizeBool(isComponent), selector, exportAs, changeDetection, isComponent: normalizeBool(isComponent), selector, exportAs, changeDetection,
inputs: inputsMap, inputs: inputsMap,
outputs: outputsMap, hostListeners, hostProperties, hostAttributes, outputs: outputsMap,
lifecycleHooks: isPresent(lifecycleHooks) ? lifecycleHooks : [], hostListeners,
hostProperties,
hostAttributes,
providers, providers,
viewProviders, viewProviders,
queries, queries,
@ -490,7 +493,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
hostListeners: {[key: string]: string}; hostListeners: {[key: string]: string};
hostProperties: {[key: string]: string}; hostProperties: {[key: string]: string};
hostAttributes: {[key: string]: string}; hostAttributes: {[key: string]: string};
lifecycleHooks: LifecycleHooks[];
providers: CompileProviderMetadata[]; providers: CompileProviderMetadata[];
viewProviders: CompileProviderMetadata[]; viewProviders: CompileProviderMetadata[];
queries: CompileQueryMetadata[]; queries: CompileQueryMetadata[];
@ -506,8 +508,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
constructor( constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners, {type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners,
hostProperties, hostAttributes, lifecycleHooks, providers, viewProviders, queries, hostProperties, hostAttributes, providers, viewProviders, queries, viewQueries,
viewQueries, entryComponents, viewDirectives, viewPipes, template}: { entryComponents, viewDirectives, viewPipes, template}: {
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
isComponent?: boolean, isComponent?: boolean,
selector?: string, selector?: string,
@ -518,7 +520,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
hostListeners?: {[key: string]: string}, hostListeners?: {[key: string]: string},
hostProperties?: {[key: string]: string}, hostProperties?: {[key: string]: string},
hostAttributes?: {[key: string]: string}, hostAttributes?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?: providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>, Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewProviders?: viewProviders?:
@ -540,7 +541,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
this.hostListeners = hostListeners; this.hostListeners = hostListeners;
this.hostProperties = hostProperties; this.hostProperties = hostProperties;
this.hostAttributes = hostAttributes; this.hostAttributes = hostAttributes;
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
this.providers = _normalizeArray(providers); this.providers = _normalizeArray(providers);
this.viewProviders = _normalizeArray(viewProviders); this.viewProviders = _normalizeArray(viewProviders);
this.queries = _normalizeArray(queries); this.queries = _normalizeArray(queries);
@ -588,7 +588,6 @@ export function createHostComponentMeta(compMeta: CompileDirectiveMetadata):
inputs: [], inputs: [],
outputs: [], outputs: [],
host: {}, host: {},
lifecycleHooks: [],
isComponent: true, isComponent: true,
selector: '*', selector: '*',
providers: [], providers: [],
@ -603,18 +602,15 @@ export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
type: CompileTypeMetadata; type: CompileTypeMetadata;
name: string; name: string;
pure: boolean; pure: boolean;
lifecycleHooks: LifecycleHooks[];
constructor({type, name, pure, lifecycleHooks}: { constructor({type, name, pure}: {
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
name?: string, name?: string,
pure?: boolean, pure?: boolean,
lifecycleHooks?: LifecycleHooks[]
} = {}) { } = {}) {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.pure = normalizeBool(pure); this.pure = normalizeBool(pure);
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
} }
get identifier(): CompileIdentifierMetadata { return this.type; } get identifier(): CompileIdentifierMetadata { return this.type; }
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; } get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }

View File

@ -248,7 +248,6 @@ function _cloneDirectiveWithTemplate(
hostListeners: directive.hostListeners, hostListeners: directive.hostListeners,
hostProperties: directive.hostProperties, hostProperties: directive.hostProperties,
hostAttributes: directive.hostAttributes, hostAttributes: directive.hostAttributes,
lifecycleHooks: directive.lifecycleHooks,
providers: directive.providers, providers: directive.providers,
viewProviders: directive.viewProviders, viewProviders: directive.viewProviders,
queries: directive.queries, queries: directive.queries,

View File

@ -208,8 +208,6 @@ export class CompileMetadataResolver {
inputs: dirMeta.inputs, inputs: dirMeta.inputs,
outputs: dirMeta.outputs, outputs: dirMeta.outputs,
host: dirMeta.host, host: dirMeta.host,
lifecycleHooks:
LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, directiveType)),
providers: providers, providers: providers,
viewProviders: viewProviders, viewProviders: viewProviders,
queries: queries, queries: queries,
@ -486,7 +484,8 @@ export class CompileMetadataResolver {
name: this.sanitizeTokenName(type), name: this.sanitizeTokenName(type),
moduleUrl: moduleUrl, moduleUrl: moduleUrl,
runtime: type, runtime: type,
diDeps: this.getDependenciesMetadata(type, dependencies) diDeps: this.getDependenciesMetadata(type, dependencies),
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, type)),
}); });
} }
@ -512,8 +511,7 @@ export class CompileMetadataResolver {
meta = new cpl.CompilePipeMetadata({ meta = new cpl.CompilePipeMetadata({
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)), type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
name: pipeMeta.name, name: pipeMeta.name,
pure: pipeMeta.pure, pure: pipeMeta.pure
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, pipeType)),
}); });
this._pipeCache.set(pipeType, meta); this._pipeCache.set(pipeType, meta);
} }

View File

@ -405,7 +405,7 @@ function _transformProviderAst(
{eager, providers}: {eager: boolean, providers: CompileProviderMetadata[]}): ProviderAst { {eager, providers}: {eager: boolean, providers: CompileProviderMetadata[]}): ProviderAst {
return new ProviderAst( return new ProviderAst(
provider.token, provider.multiProvider, provider.eager || eager, providers, provider.token, provider.multiProvider, provider.eager || eager, providers,
provider.providerType, provider.sourceSpan); provider.providerType, provider.lifecycleHooks, provider.sourceSpan);
} }
function _normalizeProviders( function _normalizeProviders(
@ -478,8 +478,10 @@ function _resolveProviders(
sourceSpan)); sourceSpan));
} }
if (isBlank(resolvedProvider)) { if (isBlank(resolvedProvider)) {
const lifecycleHooks = provider.useClass ? provider.useClass.lifecycleHooks : [];
resolvedProvider = new ProviderAst( resolvedProvider = new ProviderAst(
provider.token, provider.multi, eager, [provider], providerType, sourceSpan); provider.token, provider.multi, eager, [provider], providerType, lifecycleHooks,
sourceSpan);
targetProvidersByToken.add(provider.token, resolvedProvider); targetProvidersByToken.add(provider.token, resolvedProvider);
} else { } else {
if (!provider.multi) { if (!provider.multi) {

View File

@ -12,6 +12,7 @@ import {isPresent} from '../facade/lang';
import {CompileDirectiveMetadata, CompileTokenMetadata, CompileProviderMetadata,} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileTokenMetadata, CompileProviderMetadata,} from '../compile_metadata';
import {ParseSourceSpan} from '../parse_util'; import {ParseSourceSpan} from '../parse_util';
import {SecurityContext} from '@angular/core'; import {SecurityContext} from '@angular/core';
import {LifecycleHooks} from '../../core_private';
/** /**
* An Abstract Syntax Tree node representing part of a parsed Angular template. * An Abstract Syntax Tree node representing part of a parsed Angular template.
@ -174,7 +175,7 @@ export class ProviderAst implements TemplateAst {
constructor( constructor(
public token: CompileTokenMetadata, public multiProvider: boolean, public eager: boolean, public token: CompileTokenMetadata, public multiProvider: boolean, public eager: boolean,
public providers: CompileProviderMetadata[], public providerType: ProviderAstType, public providers: CompileProviderMetadata[], public providerType: ProviderAstType,
public sourceSpan: ParseSourceSpan) {} public lifecycleHooks: LifecycleHooks[], public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
// No visit method in the visitor for now... // No visit method in the visitor for now...

View File

@ -109,7 +109,7 @@ export class CompileElement extends CompileNode {
// ProviderAstType.PrivateService as only the component and its view can see it, // ProviderAstType.PrivateService as only the component and its view can see it,
// but nobody else // but nobody else
this._resolvedProvidersArray.unshift(new ProviderAst( this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.PrivateService, provider.token, false, true, [provider], ProviderAstType.PrivateService, [],
this.sourceAst.sourceSpan)); this.sourceAst.sourceSpan));
} }
@ -132,7 +132,7 @@ export class CompileElement extends CompileNode {
{token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr}); {token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
// Add TemplateRef as first provider as it does not have deps on other providers // Add TemplateRef as first provider as it does not have deps on other providers
this._resolvedProvidersArray.unshift(new ProviderAst( this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.Builtin, provider.token, false, true, [provider], ProviderAstType.Builtin, [],
this.sourceAst.sourceSpan)); this.sourceAst.sourceSpan));
} }
} }

View File

@ -24,7 +24,7 @@ export function bindDirectiveDetectChangesLifecycleCallbacks(
directiveAst: DirectiveAst, directiveInstance: o.Expression, compileElement: CompileElement) { directiveAst: DirectiveAst, directiveInstance: o.Expression, compileElement: CompileElement) {
var view = compileElement.view; var view = compileElement.view;
var detectChangesInInputsMethod = view.detectChangesInInputsMethod; var detectChangesInInputsMethod = view.detectChangesInInputsMethod;
var lifecycleHooks = directiveAst.directive.lifecycleHooks; var lifecycleHooks = directiveAst.directive.type.lifecycleHooks;
if (lifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1 && directiveAst.inputs.length > 0) { if (lifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1 && directiveAst.inputs.length > 0) {
detectChangesInInputsMethod.addStmt(new o.IfStmt( detectChangesInInputsMethod.addStmt(new o.IfStmt(
DetectChangesVars.changes.notIdentical(o.NULL_EXPR), DetectChangesVars.changes.notIdentical(o.NULL_EXPR),
@ -45,7 +45,7 @@ export function bindDirectiveAfterContentLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression, directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) { compileElement: CompileElement) {
var view = compileElement.view; var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks; var lifecycleHooks = directiveMeta.type.lifecycleHooks;
var afterContentLifecycleCallbacksMethod = view.afterContentLifecycleCallbacksMethod; var afterContentLifecycleCallbacksMethod = view.afterContentLifecycleCallbacksMethod;
afterContentLifecycleCallbacksMethod.resetDebugInfo( afterContentLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst); compileElement.nodeIndex, compileElement.sourceAst);
@ -63,7 +63,7 @@ export function bindDirectiveAfterViewLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression, directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) { compileElement: CompileElement) {
var view = compileElement.view; var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks; var lifecycleHooks = directiveMeta.type.lifecycleHooks;
var afterViewLifecycleCallbacksMethod = view.afterViewLifecycleCallbacksMethod; var afterViewLifecycleCallbacksMethod = view.afterViewLifecycleCallbacksMethod;
afterViewLifecycleCallbacksMethod.resetDebugInfo( afterViewLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst); compileElement.nodeIndex, compileElement.sourceAst);
@ -82,7 +82,7 @@ export function bindDirectiveDestroyLifecycleCallbacks(
compileElement: CompileElement) { compileElement: CompileElement) {
var onDestroyMethod = compileElement.view.destroyMethod; var onDestroyMethod = compileElement.view.destroyMethod;
onDestroyMethod.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst); onDestroyMethod.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst);
if (directiveMeta.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) { if (directiveMeta.type.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) {
onDestroyMethod.addStmt(directiveInstance.callMethod('ngOnDestroy', []).toStmt()); onDestroyMethod.addStmt(directiveInstance.callMethod('ngOnDestroy', []).toStmt());
} }
} }
@ -90,7 +90,7 @@ export function bindDirectiveDestroyLifecycleCallbacks(
export function bindPipeDestroyLifecycleCallbacks( export function bindPipeDestroyLifecycleCallbacks(
pipeMeta: CompilePipeMetadata, pipeInstance: o.Expression, view: CompileView) { pipeMeta: CompilePipeMetadata, pipeInstance: o.Expression, view: CompileView) {
var onDestroyMethod = view.destroyMethod; var onDestroyMethod = view.destroyMethod;
if (pipeMeta.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) { if (pipeMeta.type.lifecycleHooks.indexOf(LifecycleHooks.OnDestroy) !== -1) {
onDestroyMethod.addStmt(pipeInstance.callMethod('ngOnDestroy', []).toStmt()); onDestroyMethod.addStmt(pipeInstance.callMethod('ngOnDestroy', []).toStmt());
} }
} }

View File

@ -234,7 +234,7 @@ export function bindDirectiveInputs(
var detectChangesInInputsMethod = view.detectChangesInInputsMethod; var detectChangesInInputsMethod = view.detectChangesInInputsMethod;
detectChangesInInputsMethod.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst); detectChangesInInputsMethod.resetDebugInfo(compileElement.nodeIndex, compileElement.sourceAst);
var lifecycleHooks = directiveAst.directive.lifecycleHooks; var lifecycleHooks = directiveAst.directive.type.lifecycleHooks;
var calcChangesMap = lifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1; var calcChangesMap = lifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1;
var isOnPushComp = directiveAst.directive.isComponent && var isOnPushComp = directiveAst.directive.isComponent &&
!isDefaultChangeDetectionStrategy(directiveAst.directive.changeDetection); !isDefaultChangeDetectionStrategy(directiveAst.directive.changeDetection);

View File

@ -32,7 +32,7 @@ export function main() {
expect(meta.isComponent).toBe(true); expect(meta.isComponent).toBe(true);
expect(meta.type.runtime).toBe(ComponentWithEverything); expect(meta.type.runtime).toBe(ComponentWithEverything);
expect(meta.type.name).toEqual(stringify(ComponentWithEverything)); expect(meta.type.name).toEqual(stringify(ComponentWithEverything));
expect(meta.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES); expect(meta.type.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES);
expect(meta.changeDetection).toBe(ChangeDetectionStrategy.Default); expect(meta.changeDetection).toBe(ChangeDetectionStrategy.Default);
expect(meta.inputs).toEqual({'someProp': 'someProp'}); expect(meta.inputs).toEqual({'someProp': 'someProp'});
expect(meta.outputs).toEqual({'someEvent': 'someEvent'}); expect(meta.outputs).toEqual({'someEvent': 'someEvent'});