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

View File

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

View File

@ -208,8 +208,6 @@ export class CompileMetadataResolver {
inputs: dirMeta.inputs,
outputs: dirMeta.outputs,
host: dirMeta.host,
lifecycleHooks:
LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, directiveType)),
providers: providers,
viewProviders: viewProviders,
queries: queries,
@ -486,7 +484,8 @@ export class CompileMetadataResolver {
name: this.sanitizeTokenName(type),
moduleUrl: moduleUrl,
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({
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
name: pipeMeta.name,
pure: pipeMeta.pure,
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, pipeType)),
pure: pipeMeta.pure
});
this._pipeCache.set(pipeType, meta);
}

View File

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

View File

@ -12,6 +12,7 @@ import {isPresent} from '../facade/lang';
import {CompileDirectiveMetadata, CompileTokenMetadata, CompileProviderMetadata,} from '../compile_metadata';
import {ParseSourceSpan} from '../parse_util';
import {SecurityContext} from '@angular/core';
import {LifecycleHooks} from '../../core_private';
/**
* An Abstract Syntax Tree node representing part of a parsed Angular template.
@ -174,7 +175,7 @@ export class ProviderAst implements TemplateAst {
constructor(
public token: CompileTokenMetadata, public multiProvider: boolean, public eager: boolean,
public providers: CompileProviderMetadata[], public providerType: ProviderAstType,
public sourceSpan: ParseSourceSpan) {}
public lifecycleHooks: LifecycleHooks[], public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
// 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,
// but nobody else
this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.PrivateService,
provider.token, false, true, [provider], ProviderAstType.PrivateService, [],
this.sourceAst.sourceSpan));
}
@ -132,7 +132,7 @@ export class CompileElement extends CompileNode {
{token: identifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
// Add TemplateRef as first provider as it does not have deps on other providers
this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.Builtin,
provider.token, false, true, [provider], ProviderAstType.Builtin, [],
this.sourceAst.sourceSpan));
}
}

View File

@ -24,7 +24,7 @@ export function bindDirectiveDetectChangesLifecycleCallbacks(
directiveAst: DirectiveAst, directiveInstance: o.Expression, compileElement: CompileElement) {
var view = compileElement.view;
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) {
detectChangesInInputsMethod.addStmt(new o.IfStmt(
DetectChangesVars.changes.notIdentical(o.NULL_EXPR),
@ -45,7 +45,7 @@ export function bindDirectiveAfterContentLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) {
var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks;
var lifecycleHooks = directiveMeta.type.lifecycleHooks;
var afterContentLifecycleCallbacksMethod = view.afterContentLifecycleCallbacksMethod;
afterContentLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst);
@ -63,7 +63,7 @@ export function bindDirectiveAfterViewLifecycleCallbacks(
directiveMeta: CompileDirectiveMetadata, directiveInstance: o.Expression,
compileElement: CompileElement) {
var view = compileElement.view;
var lifecycleHooks = directiveMeta.lifecycleHooks;
var lifecycleHooks = directiveMeta.type.lifecycleHooks;
var afterViewLifecycleCallbacksMethod = view.afterViewLifecycleCallbacksMethod;
afterViewLifecycleCallbacksMethod.resetDebugInfo(
compileElement.nodeIndex, compileElement.sourceAst);
@ -82,7 +82,7 @@ export function bindDirectiveDestroyLifecycleCallbacks(
compileElement: CompileElement) {
var onDestroyMethod = compileElement.view.destroyMethod;
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());
}
}
@ -90,7 +90,7 @@ export function bindDirectiveDestroyLifecycleCallbacks(
export function bindPipeDestroyLifecycleCallbacks(
pipeMeta: CompilePipeMetadata, pipeInstance: o.Expression, view: CompileView) {
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());
}
}

View File

@ -234,7 +234,7 @@ export function bindDirectiveInputs(
var detectChangesInInputsMethod = view.detectChangesInInputsMethod;
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 isOnPushComp = directiveAst.directive.isComponent &&
!isDefaultChangeDetectionStrategy(directiveAst.directive.changeDetection);

View File

@ -32,7 +32,7 @@ export function main() {
expect(meta.isComponent).toBe(true);
expect(meta.type.runtime).toBe(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.inputs).toEqual({'someProp': 'someProp'});
expect(meta.outputs).toEqual({'someEvent': 'someEvent'});