diff --git a/modules/angular2/metadata.ts b/modules/angular2/metadata.ts index 515f85817a..161946e781 100644 --- a/modules/angular2/metadata.ts +++ b/modules/angular2/metadata.ts @@ -38,7 +38,10 @@ export { } from './src/core/metadata'; export { + AfterContentInit, AfterContentChecked, + AfterViewInit, + AfterViewChecked, OnChanges, OnDestroy, OnInit, diff --git a/modules/angular2/src/core/change_detection/abstract_change_detector.ts b/modules/angular2/src/core/change_detection/abstract_change_detector.ts index 95d4bbcd6e..80b1b6022f 100644 --- a/modules/angular2/src/core/change_detection/abstract_change_detector.ts +++ b/modules/angular2/src/core/change_detection/abstract_change_detector.ts @@ -82,12 +82,19 @@ export class AbstractChangeDetector implements ChangeDetector { this.mode === ChangeDetectionStrategy.Checked) return; var s = _scope_check(this.id, throwOnChange); + this.detectChangesInRecords(throwOnChange); + this._detectChangesInLightDomChildren(throwOnChange); - if (throwOnChange === false) this.callAfterContentChecked(); + if (!throwOnChange) this.afterContentLifecycleCallbacks(); + this._detectChangesInShadowDomChildren(throwOnChange); + if (!throwOnChange) this.afterViewLifecycleCallbacks(); + if (this.mode === ChangeDetectionStrategy.CheckOnce) this.mode = ChangeDetectionStrategy.Checked; + + this.alreadyChecked = true; wtfLeave(s); } @@ -156,7 +163,19 @@ export class AbstractChangeDetector implements ChangeDetector { hydrated(): boolean { return this.context !== null; } - callAfterContentChecked(): void { this.dispatcher.notifyAfterContentChecked(); } + afterContentLifecycleCallbacks(): void { + this.dispatcher.notifyAfterContentChecked(); + this.afterContentLifecycleCallbacksInternal(); + } + + afterContentLifecycleCallbacksInternal(): void {} + + afterViewLifecycleCallbacks(): void { + this.dispatcher.notifyAfterViewChecked(); + this.afterViewLifecycleCallbacksInternal(); + } + + afterViewLifecycleCallbacksInternal(): void {} _detectChangesInLightDomChildren(throwOnChange: boolean): void { var c = this.lightDomChildren; diff --git a/modules/angular2/src/core/change_detection/change_detection_jit_generator.ts b/modules/angular2/src/core/change_detection/change_detection_jit_generator.ts index ef2378ac0a..4cddcfb356 100644 --- a/modules/angular2/src/core/change_detection/change_detection_jit_generator.ts +++ b/modules/angular2/src/core/change_detection/change_detection_jit_generator.ts @@ -63,23 +63,23 @@ export class ChangeDetectorJITGenerator { var ${CHANGES_LOCAL} = null; ${this.records.map((r) => this._genRecord(r)).join("\n")} - - ${this._names.getAlreadyCheckedName()} = true; } ${this._maybeGenHandleEventInternal()} ${this._genCheckNoChanges()} - ${this._maybeGenCallAfterContentChecked()} + ${this._maybeGenAfterContentLifecycleCallbacks()} + + ${this._maybeGenAfterViewLifecycleCallbacks()} ${this._maybeGenHydrateDirectives()} ${this._maybeGenDehydrateDirectives()} - ${this._genPropertyBindingTargets()}; + ${this._genPropertyBindingTargets()} - ${this._genDirectiveIndices()}; + ${this._genDirectiveIndices()} return function(dispatcher) { return new ${this._typeName}(dispatcher); @@ -172,23 +172,26 @@ export class ChangeDetectorJITGenerator { }`; } - _maybeGenCallAfterContentChecked(): string { - var notifications = []; - var dirs = this.directiveRecords; - - // NOTE(kegluneq): Order is important! - for (var i = dirs.length - 1; i >= 0; --i) { - var dir = dirs[i]; - if (dir.callAfterContentChecked) { - notifications.push( - `${this._names.getDirectiveName(dir.directiveIndex)}.afterContentChecked();`); - } - } + _maybeGenAfterContentLifecycleCallbacks(): string { + var notifications = this._logic.genContentLifecycleCallbacks(this.directiveRecords); if (notifications.length > 0) { var directiveNotifications = notifications.join("\n"); return ` - ${this._typeName}.prototype.callAfterContentChecked = function() { - ${ABSTRACT_CHANGE_DETECTOR}.prototype.callAfterContentChecked.call(this); + ${this._typeName}.prototype.afterContentLifecycleCallbacksInternal = function() { + ${directiveNotifications} + } + `; + } else { + return ''; + } + } + + _maybeGenAfterViewLifecycleCallbacks(): string { + var notifications = this._logic.genViewLifecycleCallbacks(this.directiveRecords); + if (notifications.length > 0) { + var directiveNotifications = notifications.join("\n"); + return ` + ${this._typeName}.prototype.afterViewLifecycleCallbacksInternal = function() { ${directiveNotifications} } `; diff --git a/modules/angular2/src/core/change_detection/codegen_logic_util.ts b/modules/angular2/src/core/change_detection/codegen_logic_util.ts index dafed6dad0..a24d568c11 100644 --- a/modules/angular2/src/core/change_detection/codegen_logic_util.ts +++ b/modules/angular2/src/core/change_detection/codegen_logic_util.ts @@ -183,4 +183,38 @@ export class CodegenLogicUtil { } return res.join("\n"); } + + genContentLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] { + var res = []; + // NOTE(kegluneq): Order is important! + for (var i = directiveRecords.length - 1; i >= 0; --i) { + var dir = directiveRecords[i]; + if (dir.callAfterContentInit) { + res.push( + `if(! ${this._names.getAlreadyCheckedName()}) ${this._names.getDirectiveName(dir.directiveIndex)}.afterContentInit();`); + } + + if (dir.callAfterContentChecked) { + res.push(`${this._names.getDirectiveName(dir.directiveIndex)}.afterContentChecked();`); + } + } + return res; + } + + genViewLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] { + var res = []; + // NOTE(kegluneq): Order is important! + for (var i = directiveRecords.length - 1; i >= 0; --i) { + var dir = directiveRecords[i]; + if (dir.callAfterViewInit) { + res.push( + `if(! ${this._names.getAlreadyCheckedName()}) ${this._names.getDirectiveName(dir.directiveIndex)}.afterViewInit();`); + } + + if (dir.callAfterViewChecked) { + res.push(`${this._names.getDirectiveName(dir.directiveIndex)}.afterViewChecked();`); + } + } + return res; + } } diff --git a/modules/angular2/src/core/change_detection/directive_record.ts b/modules/angular2/src/core/change_detection/directive_record.ts index e67dac2e32..3d0768c99b 100644 --- a/modules/angular2/src/core/change_detection/directive_record.ts +++ b/modules/angular2/src/core/change_detection/directive_record.ts @@ -9,24 +9,33 @@ export class DirectiveIndex { export class DirectiveRecord { directiveIndex: DirectiveIndex; + callAfterContentInit: boolean; callAfterContentChecked: boolean; + callAfterViewInit: boolean; + callAfterViewChecked: boolean; callOnChanges: boolean; callDoCheck: boolean; callOnInit: boolean; changeDetection: ChangeDetectionStrategy; - constructor({directiveIndex, callAfterContentChecked, callOnChanges, callDoCheck, callOnInit, - changeDetection}: { + constructor({directiveIndex, callAfterContentInit, callAfterContentChecked, callAfterViewInit, + callAfterViewChecked, callOnChanges, callDoCheck, callOnInit, changeDetection}: { directiveIndex?: DirectiveIndex, + callAfterContentInit?: boolean, callAfterContentChecked?: boolean, + callAfterViewInit?: boolean, + callAfterViewChecked?: boolean, callOnChanges?: boolean, callDoCheck?: boolean, callOnInit?: boolean, changeDetection?: ChangeDetectionStrategy } = {}) { this.directiveIndex = directiveIndex; + this.callAfterContentInit = normalizeBool(callAfterContentInit); this.callAfterContentChecked = normalizeBool(callAfterContentChecked); this.callOnChanges = normalizeBool(callOnChanges); + this.callAfterViewInit = normalizeBool(callAfterViewInit); + this.callAfterViewChecked = normalizeBool(callAfterViewChecked); this.callDoCheck = normalizeBool(callDoCheck); this.callOnInit = normalizeBool(callOnInit); this.changeDetection = changeDetection; diff --git a/modules/angular2/src/core/change_detection/dynamic_change_detector.ts b/modules/angular2/src/core/change_detection/dynamic_change_detector.ts index a2b100c2e8..1cb9b1152b 100644 --- a/modules/angular2/src/core/change_detection/dynamic_change_detector.ts +++ b/modules/angular2/src/core/change_detection/dynamic_change_detector.ts @@ -159,8 +159,6 @@ export class DynamicChangeDetector extends AbstractChangeDetector { isChanged = false; } } - - this.alreadyChecked = true; } _firstInBinding(r: ProtoRecord): boolean { @@ -168,17 +166,33 @@ export class DynamicChangeDetector extends AbstractChangeDetector { return isBlank(prev) || prev.bindingRecord !== r.bindingRecord; } - callAfterContentChecked() { - super.callAfterContentChecked(); + afterContentLifecycleCallbacksInternal() { var dirs = this.directiveRecords; for (var i = dirs.length - 1; i >= 0; --i) { var dir = dirs[i]; + if (dir.callAfterContentInit && !this.alreadyChecked) { + this._getDirectiveFor(dir.directiveIndex).afterContentInit(); + } + if (dir.callAfterContentChecked) { this._getDirectiveFor(dir.directiveIndex).afterContentChecked(); } } } + afterViewLifecycleCallbacksInternal() { + var dirs = this.directiveRecords; + for (var i = dirs.length - 1; i >= 0; --i) { + var dir = dirs[i]; + if (dir.callAfterViewInit && !this.alreadyChecked) { + this._getDirectiveFor(dir.directiveIndex).afterViewInit(); + } + if (dir.callAfterViewChecked) { + this._getDirectiveFor(dir.directiveIndex).afterViewChecked(); + } + } + } + _updateDirectiveOrElement(change, bindingRecord) { if (isBlank(bindingRecord.directiveRecord)) { super.notifyDispatcher(change.currentValue); diff --git a/modules/angular2/src/core/change_detection/interfaces.ts b/modules/angular2/src/core/change_detection/interfaces.ts index 9f00c3f50d..2c074fbe30 100644 --- a/modules/angular2/src/core/change_detection/interfaces.ts +++ b/modules/angular2/src/core/change_detection/interfaces.ts @@ -52,6 +52,7 @@ export interface ChangeDispatcher { notifyOnBinding(bindingTarget: BindingTarget, value: any): void; logBindingUpdate(bindingTarget: BindingTarget, value: any): void; notifyAfterContentChecked(): void; + notifyAfterViewChecked(): void; } export interface ChangeDetector { diff --git a/modules/angular2/src/core/compiler/directive_lifecycle_reflector.dart b/modules/angular2/src/core/compiler/directive_lifecycle_reflector.dart index 82936a350a..1b41840705 100644 --- a/modules/angular2/src/core/compiler/directive_lifecycle_reflector.dart +++ b/modules/angular2/src/core/compiler/directive_lifecycle_reflector.dart @@ -17,8 +17,14 @@ bool hasLifecycleHook(LifecycleEvent e, type, DirectiveMetadata annotation) { interface = OnChanges; } else if (e == LifecycleEvent.OnDestroy) { interface = OnDestroy; + } else if (e == LifecycleEvent.AfterContentInit) { + interface = AfterContentInit; } else if (e == LifecycleEvent.AfterContentChecked) { interface = AfterContentChecked; + } else if (e == LifecycleEvent.AfterViewInit) { + interface = AfterViewInit; + } else if (e == LifecycleEvent.AfterViewChecked) { + interface = AfterViewChecked; } else if (e == LifecycleEvent.DoCheck) { interface = DoCheck; } else if (e == LifecycleEvent.OnInit) { diff --git a/modules/angular2/src/core/compiler/directive_lifecycle_reflector.ts b/modules/angular2/src/core/compiler/directive_lifecycle_reflector.ts index bcbe6a51c7..9ed1c4a801 100644 --- a/modules/angular2/src/core/compiler/directive_lifecycle_reflector.ts +++ b/modules/angular2/src/core/compiler/directive_lifecycle_reflector.ts @@ -8,8 +8,14 @@ export function hasLifecycleHook(e: LifecycleEvent, type, annotation: DirectiveM if (!(type instanceof Type)) return false; var proto = (type).prototype; switch (e) { + case LifecycleEvent.AfterContentInit: + return !!proto.afterContentInit; case LifecycleEvent.AfterContentChecked: return !!proto.afterContentChecked; + case LifecycleEvent.AfterViewInit: + return !!proto.afterViewInit; + case LifecycleEvent.AfterViewChecked: + return !!proto.afterViewChecked; case LifecycleEvent.OnChanges: return !!proto.onChanges; case LifecycleEvent.DoCheck: diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index c4edd73df3..313b68092d 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -216,38 +216,41 @@ export class DirectiveBinding extends ResolvedBinding { get changeDetection() { return this.metadata.changeDetection; } - static createFromBinding(binding: Binding, ann: DirectiveMetadata): DirectiveBinding { - if (isBlank(ann)) { - ann = new DirectiveMetadata(); + static createFromBinding(binding: Binding, meta: DirectiveMetadata): DirectiveBinding { + if (isBlank(meta)) { + meta = new DirectiveMetadata(); } var rb = binding.resolve(); var deps = ListWrapper.map(rb.dependencies, DirectiveDependency.createFrom); - var resolvedBindings = isPresent(ann.bindings) ? Injector.resolve(ann.bindings) : []; - var resolvedViewBindings = ann instanceof ComponentMetadata && isPresent(ann.viewBindings) ? - Injector.resolve(ann.viewBindings) : + var resolvedBindings = isPresent(meta.bindings) ? Injector.resolve(meta.bindings) : []; + var resolvedViewBindings = meta instanceof ComponentMetadata && isPresent(meta.viewBindings) ? + Injector.resolve(meta.viewBindings) : []; var metadata = RenderDirectiveMetadata.create({ id: stringify(rb.key.token), - type: ann instanceof ComponentMetadata ? RenderDirectiveMetadata.COMPONENT_TYPE : - RenderDirectiveMetadata.DIRECTIVE_TYPE, - selector: ann.selector, - compileChildren: ann.compileChildren, - events: ann.events, - host: isPresent(ann.host) ? MapWrapper.createFromStringMap(ann.host) : null, - properties: ann.properties, + type: meta instanceof ComponentMetadata ? RenderDirectiveMetadata.COMPONENT_TYPE : + RenderDirectiveMetadata.DIRECTIVE_TYPE, + selector: meta.selector, + compileChildren: meta.compileChildren, + events: meta.events, + host: isPresent(meta.host) ? MapWrapper.createFromStringMap(meta.host) : null, + properties: meta.properties, readAttributes: DirectiveBinding._readAttributes(deps), - callOnDestroy: hasLifecycleHook(LifecycleEvent.OnDestroy, rb.key.token, ann), - callOnChanges: hasLifecycleHook(LifecycleEvent.OnChanges, rb.key.token, ann), - callDoCheck: hasLifecycleHook(LifecycleEvent.DoCheck, rb.key.token, ann), - callOnInit: hasLifecycleHook(LifecycleEvent.OnInit, rb.key.token, ann), + callOnDestroy: hasLifecycleHook(LifecycleEvent.OnDestroy, rb.key.token, meta), + callOnChanges: hasLifecycleHook(LifecycleEvent.OnChanges, rb.key.token, meta), + callDoCheck: hasLifecycleHook(LifecycleEvent.DoCheck, rb.key.token, meta), + callOnInit: hasLifecycleHook(LifecycleEvent.OnInit, rb.key.token, meta), + callAfterContentInit: hasLifecycleHook(LifecycleEvent.AfterContentInit, rb.key.token, meta), callAfterContentChecked: - hasLifecycleHook(LifecycleEvent.AfterContentChecked, rb.key.token, ann), + hasLifecycleHook(LifecycleEvent.AfterContentChecked, rb.key.token, meta), + callAfterViewInit: hasLifecycleHook(LifecycleEvent.AfterViewInit, rb.key.token, meta), + callAfterViewChecked: hasLifecycleHook(LifecycleEvent.AfterViewChecked, rb.key.token, meta), - changeDetection: ann instanceof ComponentMetadata ? ann.changeDetection : null, + changeDetection: meta instanceof ComponentMetadata ? meta.changeDetection : null, - exportAs: ann.exportAs + exportAs: meta.exportAs }); return new DirectiveBinding(rb.key, rb.factory, deps, resolvedBindings, resolvedViewBindings, metadata); diff --git a/modules/angular2/src/core/compiler/interfaces.ts b/modules/angular2/src/core/compiler/interfaces.ts index 9871eb874d..b69425a6f9 100644 --- a/modules/angular2/src/core/compiler/interfaces.ts +++ b/modules/angular2/src/core/compiler/interfaces.ts @@ -29,9 +29,30 @@ export interface DoCheck { doCheck(): boolean; } */ export interface OnDestroy { onDestroy(): void; } +/** + * Defines lifecycle method + * {@link metadata/LifeCycleEvent#AfterContentInit `LifeCycleEvent.afterContentInit`} + * called when the bindings of all its content children have been checked the first time. + */ +export interface AfterContentInit { afterContentInit(): void; } + /** * Defines lifecycle method * {@link metadata/LifeCycleEvent#AfterContentChecked `LifeCycleEvent.afterContentChecked`} - * called when the bindings of all its view children have been changed. + * called when the bindings of all its content children have been checked. */ export interface AfterContentChecked { afterContentChecked(): void; } + +/** + * Defines lifecycle method + * {@link metadata/LifeCycleEvent#AfterViewInit `LifeCycleEvent.afterViewInit`} + * called when the bindings of all its view children have been checked the first time. + */ +export interface AfterViewInit { afterViewInit(): void; } + +/** + * Defines lifecycle method + * {@link metadata/LifeCycleEvent#AfterViewChecked `LifeCycleEvent.afterViewChecked`} + * called when the bindings of all its view children have been checked. + */ +export interface AfterViewChecked { afterViewChecked(): void; } diff --git a/modules/angular2/src/core/compiler/proto_view_factory.ts b/modules/angular2/src/core/compiler/proto_view_factory.ts index 54d82b8fdc..aaa9db2ccb 100644 --- a/modules/angular2/src/core/compiler/proto_view_factory.ts +++ b/modules/angular2/src/core/compiler/proto_view_factory.ts @@ -191,7 +191,10 @@ export class BindingRecordsCreator { this._directiveRecordsMap.set( id, new DirectiveRecord({ directiveIndex: new DirectiveIndex(boundElementIndex, directiveIndex), + callAfterContentInit: directiveMetadata.callAfterContentInit, callAfterContentChecked: directiveMetadata.callAfterContentChecked, + callAfterViewInit: directiveMetadata.callAfterViewInit, + callAfterViewChecked: directiveMetadata.callAfterViewChecked, callOnChanges: directiveMetadata.callOnChanges, callDoCheck: directiveMetadata.callDoCheck, callOnInit: directiveMetadata.callOnInit, diff --git a/modules/angular2/src/core/compiler/view.ts b/modules/angular2/src/core/compiler/view.ts index 425477abee..87781f3b96 100644 --- a/modules/angular2/src/core/compiler/view.ts +++ b/modules/angular2/src/core/compiler/view.ts @@ -212,6 +212,10 @@ export class AppView implements ChangeDispatcher, RenderEventDispatcher { } } + notifyAfterViewChecked(): void { + // required for query + } + getDirectiveFor(directive: DirectiveIndex): any { var elementInjector = this.elementInjectors[this.elementOffset + directive.elementIndex]; return elementInjector.getDirectiveAtIndex(directive.directiveIndex); diff --git a/modules/angular2/src/core/metadata/directives.ts b/modules/angular2/src/core/metadata/directives.ts index 0e45a25a7f..b795794d53 100644 --- a/modules/angular2/src/core/metadata/directives.ts +++ b/modules/angular2/src/core/metadata/directives.ts @@ -961,7 +961,30 @@ export enum LifecycleEvent { DoCheck, /** - * Notify a directive when the bindings of all its view children have been checked (whether they + * Notify a directive when the bindings of all its content children have been checked the first + * time (whether they + * have changed or not). + * + * ## Example + * + * ``` + * @Directive({ + * selector: '[class-set]', + * lifecycle: [LifecycleEvent.AfterContentInit] + * }) + * class ClassSet { + * + * afterContentInit() { + * } + * + * } + * ``` + */ + AfterContentInit, + + /** + * Notify a directive when the bindings of all its content children have been checked (whether + * they * have changed or not). * * ## Example @@ -979,7 +1002,50 @@ export enum LifecycleEvent { * } * ``` */ - AfterContentChecked + AfterContentChecked, + + /** + * Notify a directive when the bindings of all its view children have been checked the first time + * (whether they + * have changed or not). + * + * ## Example + * + * ``` + * @Directive({ + * selector: '[class-set]', + * lifecycle: [LifecycleEvent.AfterViewInit] + * }) + * class ClassSet { + * + * afterViewInit() { + * } + * + * } + * ``` + */ + AfterViewInit, + + /** + * Notify a directive when the bindings of all its view children have been checked (whether they + * have changed or not). + * + * ## Example + * + * ``` + * @Directive({ + * selector: '[class-set]', + * lifecycle: [LifecycleEvent.AfterViewChecked] + * }) + * class ClassSet { + * + * afterViewChecked() { + * } + * + * } + * ``` + */ + AfterViewChecked } /** diff --git a/modules/angular2/src/core/render/api.ts b/modules/angular2/src/core/render/api.ts index b9802491d5..5faae24d16 100644 --- a/modules/angular2/src/core/render/api.ts +++ b/modules/angular2/src/core/render/api.ts @@ -157,7 +157,10 @@ export class RenderDirectiveMetadata { callOnChanges: boolean; callDoCheck: boolean; callOnInit: boolean; + callAfterContentInit: boolean; callAfterContentChecked: boolean; + callAfterViewInit: boolean; + callAfterViewChecked: boolean; changeDetection: ChangeDetectionStrategy; exportAs: string; hostListeners: Map; @@ -169,7 +172,8 @@ export class RenderDirectiveMetadata { constructor({id, selector, compileChildren, events, hostListeners, hostProperties, hostAttributes, properties, readAttributes, type, callOnDestroy, callOnChanges, callDoCheck, - callOnInit, callAfterContentChecked, changeDetection, exportAs}: { + callOnInit, callAfterContentInit, callAfterContentChecked, callAfterViewInit, + callAfterViewChecked, changeDetection, exportAs}: { id?: string, selector?: string, compileChildren?: boolean, @@ -184,7 +188,10 @@ export class RenderDirectiveMetadata { callOnChanges?: boolean, callDoCheck?: boolean, callOnInit?: boolean, + callAfterContentInit?: boolean, callAfterContentChecked?: boolean, + callAfterViewInit?: boolean, + callAfterViewChecked?: boolean, changeDetection?: ChangeDetectionStrategy, exportAs?: string }) { @@ -202,14 +209,18 @@ export class RenderDirectiveMetadata { this.callOnChanges = callOnChanges; this.callDoCheck = callDoCheck; this.callOnInit = callOnInit; + this.callAfterContentInit = callAfterContentInit; this.callAfterContentChecked = callAfterContentChecked; + this.callAfterViewInit = callAfterViewInit; + this.callAfterViewChecked = callAfterViewChecked; this.changeDetection = changeDetection; this.exportAs = exportAs; } static create({id, selector, compileChildren, events, host, properties, readAttributes, type, - callOnDestroy, callOnChanges, callDoCheck, callOnInit, callAfterContentChecked, - changeDetection, exportAs}: { + callOnDestroy, callOnChanges, callDoCheck, callOnInit, callAfterContentInit, + callAfterContentChecked, callAfterViewInit, callAfterViewChecked, changeDetection, + exportAs}: { id?: string, selector?: string, compileChildren?: boolean, @@ -222,7 +233,10 @@ export class RenderDirectiveMetadata { callOnChanges?: boolean, callDoCheck?: boolean, callOnInit?: boolean, + callAfterContentInit?: boolean, callAfterContentChecked?: boolean, + callAfterViewInit?: boolean, + callAfterViewChecked?: boolean, changeDetection?: ChangeDetectionStrategy, exportAs?: string }): RenderDirectiveMetadata { @@ -258,7 +272,10 @@ export class RenderDirectiveMetadata { callOnChanges: callOnChanges, callDoCheck: callDoCheck, callOnInit: callOnInit, + callAfterContentInit: callAfterContentInit, callAfterContentChecked: callAfterContentChecked, + callAfterViewInit: callAfterViewInit, + callAfterViewChecked: callAfterViewChecked, changeDetection: changeDetection, exportAs: exportAs }); diff --git a/modules/angular2/src/test_lib/utils.ts b/modules/angular2/src/test_lib/utils.ts index 7a10fca7fd..1cf150da39 100644 --- a/modules/angular2/src/test_lib/utils.ts +++ b/modules/angular2/src/test_lib/utils.ts @@ -19,6 +19,8 @@ export class Log { return (a1 = null, a2 = null, a3 = null, a4 = null, a5 = null) => { this._result.push(value); } } + clear(): void { this._result = []; } + result(): string { return ListWrapper.join(this._result, "; "); } } diff --git a/modules/angular2/test/core/change_detection/change_detector_config.ts b/modules/angular2/test/core/change_detection/change_detector_config.ts index f6f5f41089..bbdb580053 100644 --- a/modules/angular2/test/core/change_detection/change_detector_config.ts +++ b/modules/angular2/test/core/change_detection/change_detector_config.ts @@ -284,13 +284,21 @@ class _DirectiveUpdating { directiveIndex: new DirectiveIndex(0, 0), callOnChanges: true, callDoCheck: true, - callAfterContentChecked: true + callOnInit: true, + callAfterContentInit: true, + callAfterContentChecked: true, + callAfterViewInit: true, + callAfterViewChecked: true }), new DirectiveRecord({ directiveIndex: new DirectiveIndex(0, 1), callOnChanges: true, callDoCheck: true, - callAfterContentChecked: true + callOnInit: true, + callAfterContentInit: true, + callAfterContentChecked: true, + callAfterViewInit: true, + callAfterViewChecked: true }) ]; @@ -298,7 +306,11 @@ class _DirectiveUpdating { directiveIndex: new DirectiveIndex(0, 0), callOnChanges: false, callDoCheck: false, - callAfterContentChecked: false + callOnInit: false, + callAfterContentInit: false, + callAfterContentChecked: false, + callAfterViewInit: false, + callAfterViewChecked: false }); /** diff --git a/modules/angular2/test/core/change_detection/change_detector_spec.ts b/modules/angular2/test/core/change_detection/change_detector_spec.ts index 18161794f1..e46c38be55 100644 --- a/modules/angular2/test/core/change_detection/change_detector_spec.ts +++ b/modules/angular2/test/core/change_detection/change_detector_spec.ts @@ -1,4 +1,3 @@ -/// import { ddescribe, describe, @@ -361,12 +360,18 @@ export function main() { }); }); - it('should notify the dispatcher on all changes done', () => { + it('should notify the dispatcher after content children have checked', () => { var val = _createChangeDetector('name', new Person('bob')); val.changeDetector.detectChanges(); expect(val.dispatcher.afterContentCheckedCalled).toEqual(true); }); + it('should notify the dispatcher after view children have been checked', () => { + var val = _createChangeDetector('name', new Person('bob')); + val.changeDetector.detectChanges(); + expect(val.dispatcher.afterViewCheckedCalled).toEqual(true); + }); + describe('updating directives', () => { var directive1; var directive2; @@ -385,148 +390,309 @@ export function main() { expect(directive1.a).toEqual(42); }); - describe('onChanges', () => { - it('should notify the directive when a group of records changes', () => { - var cd = _createWithoutHydrate('groupChanges').changeDetector; - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), - null); - cd.detectChanges(); - expect(directive1.changes).toEqual({'a': 1, 'b': 2}); - expect(directive2.changes).toEqual({'a': 3}); + describe('lifecycle', () => { + describe('onChanges', () => { + it('should notify the directive when a group of records changes', () => { + var cd = _createWithoutHydrate('groupChanges').changeDetector; + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + cd.detectChanges(); + expect(directive1.changes).toEqual({'a': 1, 'b': 2}); + expect(directive2.changes).toEqual({'a': 3}); + }); + }); + + describe('doCheck', () => { + it('should notify the directive when it is checked', () => { + var cd = _createWithoutHydrate('directiveDoCheck').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + cd.detectChanges(); + + expect(directive1.doCheckCalled).toBe(true); + directive1.doCheckCalled = false; + + cd.detectChanges(); + expect(directive1.doCheckCalled).toBe(true); + }); + + it('should not call doCheck in detectNoChanges', () => { + var cd = _createWithoutHydrate('directiveDoCheck').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.checkNoChanges(); + + expect(directive1.doCheckCalled).toBe(false); + }); + }); + + describe('onInit', () => { + it('should notify the directive after it has been checked the first time', () => { + var cd = _createWithoutHydrate('directiveOnInit').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + + cd.detectChanges(); + + expect(directive1.onInitCalled).toBe(true); + + directive1.onInitCalled = false; + + cd.detectChanges(); + + expect(directive1.onInitCalled).toBe(false); + }); + + it('should not call onInit in detectNoChanges', () => { + var cd = _createWithoutHydrate('directiveOnInit').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.checkNoChanges(); + + expect(directive1.onInitCalled).toBe(false); + }); + }); + + describe('afterContentInit', () => { + it('should be called after processing the content children', () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + + cd.detectChanges(); + + expect(directive1.afterContentInitCalled).toBe(true); + expect(directive2.afterContentInitCalled).toBe(true); + + // reset directives + directive1.afterContentInitCalled = false; + directive2.afterContentInitCalled = false; + + // Verify that checking should not call them. + cd.checkNoChanges(); + + expect(directive1.afterContentInitCalled).toBe(false); + expect(directive2.afterContentInitCalled).toBe(false); + + // re-verify that changes should not call them + cd.detectChanges(); + + expect(directive1.afterContentInitCalled).toBe(false); + expect(directive2.afterContentInitCalled).toBe(false); + }); + + it('should not be called when afterContentInit is false', () => { + var cd = _createWithoutHydrate('noCallbacks').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.detectChanges(); + + expect(directive1.afterContentInitCalled).toEqual(false); + }); + }); + + describe('afterContentChecked', () => { + it('should be called after processing all the children', () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + + cd.detectChanges(); + + expect(directive1.afterContentCheckedCalled).toBe(true); + expect(directive2.afterContentCheckedCalled).toBe(true); + + // reset directives + directive1.afterContentCheckedCalled = false; + directive2.afterContentCheckedCalled = false; + + // Verify that checking should not call them. + cd.checkNoChanges(); + + expect(directive1.afterContentCheckedCalled).toBe(false); + expect(directive2.afterContentCheckedCalled).toBe(false); + + // re-verify that changes are still detected + cd.detectChanges(); + + expect(directive1.afterContentCheckedCalled).toBe(true); + expect(directive2.afterContentCheckedCalled).toBe(true); + }); + + it('should not be called when afterContentChecked is false', () => { + var cd = _createWithoutHydrate('noCallbacks').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.detectChanges(); + + expect(directive1.afterContentCheckedCalled).toEqual(false); + }); + + it('should be called in reverse order so the child is always notified before the parent', + () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + + var onChangesDoneCalls = []; + var td1; + td1 = new TestDirective(() => onChangesDoneCalls.push(td1)); + var td2; + td2 = new TestDirective(() => onChangesDoneCalls.push(td2)); + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([td1, td2], []), null); + + cd.detectChanges(); + + expect(onChangesDoneCalls).toEqual([td2, td1]); + }); + + it('should be called before processing view children', () => { + var parent = _createWithoutHydrate('directNoDispatcher').changeDetector; + var child = _createWithoutHydrate('directNoDispatcher').changeDetector; + parent.addShadowDomChild(child); + + var orderOfOperations = []; + + var directiveInShadowDom; + directiveInShadowDom = + new TestDirective(() => { orderOfOperations.push(directiveInShadowDom); }); + var parentDirective; + parentDirective = + new TestDirective(() => { orderOfOperations.push(parentDirective); }); + + parent.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([parentDirective], []), + null); + child.hydrate(_DEFAULT_CONTEXT, null, + new FakeDirectives([directiveInShadowDom], []), null); + + parent.detectChanges(); + expect(orderOfOperations).toEqual([parentDirective, directiveInShadowDom]); + }); + }); + + + describe('afterViewInit', () => { + it('should be called after processing the view children', () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + + cd.detectChanges(); + + expect(directive1.afterViewInitCalled).toBe(true); + expect(directive2.afterViewInitCalled).toBe(true); + + // reset directives + directive1.afterViewInitCalled = false; + directive2.afterViewInitCalled = false; + + // Verify that checking should not call them. + cd.checkNoChanges(); + + expect(directive1.afterViewInitCalled).toBe(false); + expect(directive2.afterViewInitCalled).toBe(false); + + // re-verify that changes should not call them + cd.detectChanges(); + + expect(directive1.afterViewInitCalled).toBe(false); + expect(directive2.afterViewInitCalled).toBe(false); + }); + + + it('should not be called when afterViewInit is false', () => { + var cd = _createWithoutHydrate('noCallbacks').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.detectChanges(); + + expect(directive1.afterViewInitCalled).toEqual(false); + }); + }); + + describe('afterViewChecked', () => { + it('should be called after processing the view children', () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), + null); + + cd.detectChanges(); + + expect(directive1.afterViewCheckedCalled).toBe(true); + expect(directive2.afterViewCheckedCalled).toBe(true); + + // reset directives + directive1.afterViewCheckedCalled = false; + directive2.afterViewCheckedCalled = false; + + // Verify that checking should not call them. + cd.checkNoChanges(); + + expect(directive1.afterViewCheckedCalled).toBe(false); + expect(directive2.afterViewCheckedCalled).toBe(false); + + // re-verify that changes should call them + cd.detectChanges(); + + expect(directive1.afterViewCheckedCalled).toBe(true); + expect(directive2.afterViewCheckedCalled).toBe(true); + }); + + it('should not be called when afterViewChecked is false', () => { + var cd = _createWithoutHydrate('noCallbacks').changeDetector; + + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); + + cd.detectChanges(); + + expect(directive1.afterViewCheckedCalled).toEqual(false); + }); + + it('should be called in reverse order so the child is always notified before the parent', + () => { + var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; + + var onChangesDoneCalls = []; + var td1; + td1 = new TestDirective(null, () => onChangesDoneCalls.push(td1)); + var td2; + td2 = new TestDirective(null, () => onChangesDoneCalls.push(td2)); + cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([td1, td2], []), null); + + cd.detectChanges(); + + expect(onChangesDoneCalls).toEqual([td2, td1]); + }); + + it('should be called after processing view children', () => { + var parent = _createWithoutHydrate('directNoDispatcher').changeDetector; + var child = _createWithoutHydrate('directNoDispatcher').changeDetector; + parent.addShadowDomChild(child); + + var orderOfOperations = []; + + var directiveInShadowDom; + directiveInShadowDom = new TestDirective( + null, () => { orderOfOperations.push(directiveInShadowDom); }); + var parentDirective; + parentDirective = + new TestDirective(null, () => { orderOfOperations.push(parentDirective); }); + + parent.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([parentDirective], []), + null); + child.hydrate(_DEFAULT_CONTEXT, null, + new FakeDirectives([directiveInShadowDom], []), null); + + parent.detectChanges(); + expect(orderOfOperations).toEqual([directiveInShadowDom, parentDirective]); + }); }); }); - describe('doCheck', () => { - it('should notify the directive when it is checked', () => { - var cd = _createWithoutHydrate('directiveDoCheck').changeDetector; - - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); - cd.detectChanges(); - - expect(directive1.doCheckCalled).toBe(true); - directive1.doCheckCalled = false; - - cd.detectChanges(); - expect(directive1.doCheckCalled).toBe(true); - }); - - it('should not call doCheck in detectNoChanges', () => { - var cd = _createWithoutHydrate('directiveDoCheck').changeDetector; - - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); - - cd.checkNoChanges(); - - expect(directive1.doCheckCalled).toBe(false); - }); - }); - - describe('onInit', () => { - it('should notify the directive after it has been checked the first time', () => { - var cd = _createWithoutHydrate('directiveOnInit').changeDetector; - - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); - - cd.detectChanges(); - - expect(directive1.onInitCalled).toBe(true); - - directive1.onInitCalled = false; - - cd.detectChanges(); - - expect(directive1.onInitCalled).toBe(false); - }); - - it('should not call onInit in detectNoChanges', () => { - var cd = _createWithoutHydrate('directiveOnInit').changeDetector; - - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); - - cd.checkNoChanges(); - - expect(directive1.onInitCalled).toBe(false); - }); - }); - - describe('afterContentChecked', () => { - it('should be called after processing all the children', () => { - var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1, directive2], []), - null); - - cd.detectChanges(); - - expect(directive1.afterContentCheckedCalled).toBe(true); - expect(directive2.afterContentCheckedCalled).toBe(true); - - // reset directives - directive1.afterContentCheckedCalled = false; - directive2.afterContentCheckedCalled = false; - - // Verify that checking should not call them. - cd.checkNoChanges(); - - expect(directive1.afterContentCheckedCalled).toBe(false); - expect(directive2.afterContentCheckedCalled).toBe(false); - - // re-verify that changes are still detected - cd.detectChanges(); - - expect(directive1.afterContentCheckedCalled).toBe(true); - expect(directive2.afterContentCheckedCalled).toBe(true); - }); - - - it('should not be called when afterContentChecked is false', () => { - var cd = _createWithoutHydrate('noCallbacks').changeDetector; - - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directive1], []), null); - - cd.detectChanges(); - - expect(directive1.afterContentCheckedCalled).toEqual(false); - }); - - it('should be called in reverse order so the child is always notified before the parent', - () => { - var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector; - - var onChangesDoneCalls = []; - var td1; - td1 = new TestDirective(() => onChangesDoneCalls.push(td1)); - var td2; - td2 = new TestDirective(() => onChangesDoneCalls.push(td2)); - cd.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([td1, td2], []), null); - - cd.detectChanges(); - - expect(onChangesDoneCalls).toEqual([td2, td1]); - }); - - it('should be called before processing shadow dom children', () => { - var parent = _createWithoutHydrate('directNoDispatcher').changeDetector; - var child = _createWithoutHydrate('directNoDispatcher').changeDetector; - parent.addShadowDomChild(child); - - var orderOfOperations = []; - - var directiveInShadowDom = null; - directiveInShadowDom = - new TestDirective(() => { orderOfOperations.push(directiveInShadowDom); }); - var parentDirective = null; - parentDirective = - new TestDirective(() => { orderOfOperations.push(parentDirective); }); - - parent.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([parentDirective], []), - null); - child.hydrate(_DEFAULT_CONTEXT, null, new FakeDirectives([directiveInShadowDom], []), - null); - - parent.detectChanges(); - expect(orderOfOperations).toEqual([parentDirective, directiveInShadowDom]); - }); - }); }); }); @@ -1104,21 +1270,17 @@ class TestDirective { a; b; changes; - afterContentCheckedCalled; - afterContentCheckedSpy; - doCheckCalled; - onInitCalled; + doCheckCalled = false; + onInitCalled = false; + + afterContentInitCalled = false; + afterContentCheckedCalled = false; + + afterViewInitCalled = false; + afterViewCheckedCalled = false; event; - constructor(onChangesDoneSpy = null) { - this.afterContentCheckedCalled = false; - this.doCheckCalled = false; - this.onInitCalled = false; - this.afterContentCheckedSpy = onChangesDoneSpy; - this.a = null; - this.b = null; - this.changes = null; - } + constructor(public afterContentCheckedSpy = null, public afterViewCheckedSpy = null) {} onEvent(event) { this.event = event; } @@ -1132,12 +1294,23 @@ class TestDirective { this.changes = r; } + afterContentInit() { this.afterContentInitCalled = true; } + afterContentChecked() { this.afterContentCheckedCalled = true; if (isPresent(this.afterContentCheckedSpy)) { this.afterContentCheckedSpy(); } } + + afterViewInit() { this.afterViewInitCalled = true; } + + afterViewChecked() { + this.afterViewCheckedCalled = true; + if (isPresent(this.afterViewCheckedSpy)) { + this.afterViewCheckedSpy(); + } + } } class Person { @@ -1183,6 +1356,7 @@ class TestDispatcher implements ChangeDispatcher { debugLog: string[]; loggedValues: List; afterContentCheckedCalled: boolean = false; + afterViewCheckedCalled: boolean = false; constructor() { this.clear(); } @@ -1201,6 +1375,7 @@ class TestDispatcher implements ChangeDispatcher { logBindingUpdate(target, value) { this.debugLog.push(`${target.name}=${this._asString(value)}`); } notifyAfterContentChecked() { this.afterContentCheckedCalled = true; } + notifyAfterViewChecked() { this.afterViewCheckedCalled = true; } getDebugContext(a, b) { return null; } diff --git a/modules/angular2/test/core/compiler/directive_lifecycle_spec.dart b/modules/angular2/test/core/compiler/directive_lifecycle_spec.dart index 69a92d8ce8..132239101c 100644 --- a/modules/angular2/test/core/compiler/directive_lifecycle_spec.dart +++ b/modules/angular2/test/core/compiler/directive_lifecycle_spec.dart @@ -88,6 +88,25 @@ main() { }); }); + describe("afterContentInit", () { + it("should be true when the directive implements AfterContentInit", () { + expect( + metadata(DirectiveImplementingAfterContentInit, new Directive()) + .callAfterContentInit).toBe(true); + }); + + it("should be true when the lifecycle includes afterContentInit", () { + expect(metadata(DirectiveNoHooks, + new Directive(lifecycle: [LifecycleEvent.AfterContentInit])) + .callAfterContentInit).toBe(true); + }); + + it("should be false otherwise", () { + expect(metadata(DirectiveNoHooks, new Directive()) + .callAfterContentInit).toBe(false); + }); + }); + describe("afterContentChecked", () { it("should be true when the directive implements AfterContentChecked", () { expect( @@ -106,6 +125,44 @@ main() { .callAfterContentChecked).toBe(false); }); }); + + describe("afterViewInit", () { + it("should be true when the directive implements AfterViewInit", () { + expect( + metadata(DirectiveImplementingAfterViewInit, new Directive()) + .callAfterViewInit).toBe(true); + }); + + it("should be true when the lifecycle includes afterViewInit", () { + expect(metadata(DirectiveNoHooks, + new Directive(lifecycle: [LifecycleEvent.AfterViewInit])) + .callAfterViewInit).toBe(true); + }); + + it("should be false otherwise", () { + expect(metadata(DirectiveNoHooks, new Directive()) + .callAfterViewInit).toBe(false); + }); + }); + + describe("afterViewChecked", () { + it("should be true when the directive implements AfterViewChecked", () { + expect( + metadata(DirectiveImplementingAfterViewChecked, new Directive()) + .callAfterViewChecked).toBe(true); + }); + + it("should be true when the lifecycle includes afterViewChecked", () { + expect(metadata(DirectiveNoHooks, + new Directive(lifecycle: [LifecycleEvent.AfterViewChecked])) + .callAfterViewChecked).toBe(true); + }); + + it("should be false otherwise", () { + expect(metadata(DirectiveNoHooks, new Directive()) + .callAfterViewChecked).toBe(false); + }); + }); }); }); } @@ -128,6 +185,18 @@ class DirectiveImplementingOnDestroy implements OnDestroy { onDestroy() {} } +class DirectiveImplementingAfterContentInit implements AfterContentInit { + afterContentInit() {} +} + class DirectiveImplementingAfterContentChecked implements AfterContentChecked { afterContentChecked() {} } + +class DirectiveImplementingAfterViewInit implements AfterViewInit { + afterViewInit() {} +} + +class DirectiveImplementingAfterViewChecked implements AfterViewChecked { + afterViewChecked() {} +} diff --git a/modules/angular2/test/core/compiler/directive_lifecycle_spec.ts b/modules/angular2/test/core/compiler/directive_lifecycle_spec.ts index 7723cfe09c..93c71fbe2e 100644 --- a/modules/angular2/test/core/compiler/directive_lifecycle_spec.ts +++ b/modules/angular2/test/core/compiler/directive_lifecycle_spec.ts @@ -102,6 +102,26 @@ export function main() { }); }); + describe("afterContentInit", () => { + it("should be true when the directive has the afterContentInit method", () => { + expect(metadata(DirectiveWithAfterContentInitMethod, new DirectiveMetadata({})) + .callAfterContentInit) + .toBe(true); + }); + + it("should be true when the lifecycle includes afterContentInit", () => { + expect(metadata(DirectiveNoHooks, + new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterContentInit]})) + .callAfterContentInit) + .toBe(true); + }); + + it("should be false otherwise", () => { + expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterContentInit) + .toBe(false); + }); + }); + describe("afterContentChecked", () => { it("should be true when the directive has the afterContentChecked method", () => { expect(metadata(DirectiveWithAfterContentCheckedMethod, new DirectiveMetadata({})) @@ -121,6 +141,46 @@ export function main() { .toBe(false); }); }); + + + describe("afterViewInit", () => { + it("should be true when the directive has the afterViewInit method", () => { + expect(metadata(DirectiveWithAfterViewInitMethod, new DirectiveMetadata({})) + .callAfterViewInit) + .toBe(true); + }); + + it("should be true when the lifecycle includes afterViewInit", () => { + expect(metadata(DirectiveNoHooks, + new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterViewInit]})) + .callAfterViewInit) + .toBe(true); + }); + + it("should be false otherwise", () => { + expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterViewInit).toBe(false); + }); + }); + + describe("afterViewChecked", () => { + it("should be true when the directive has the afterViewChecked method", () => { + expect(metadata(DirectiveWithAfterViewCheckedMethod, new DirectiveMetadata({})) + .callAfterViewChecked) + .toBe(true); + }); + + it("should be true when the lifecycle includes afterViewChecked", () => { + expect(metadata(DirectiveNoHooks, + new DirectiveMetadata({lifecycle: [LifecycleEvent.AfterViewChecked]})) + .callAfterViewChecked) + .toBe(true); + }); + + it("should be false otherwise", () => { + expect(metadata(DirectiveNoHooks, new DirectiveMetadata()).callAfterViewChecked) + .toBe(false); + }); + }); }); }); } @@ -143,6 +203,18 @@ class DirectiveWithOnDestroyMethod { onDestroy(_) {} } +class DirectiveWithAfterContentInitMethod { + afterContentInit() {} +} + class DirectiveWithAfterContentCheckedMethod { afterContentChecked() {} } + +class DirectiveWithAfterViewInitMethod { + afterViewInit() {} +} + +class DirectiveWithAfterViewCheckedMethod { + afterViewChecked() {} +} diff --git a/modules/angular2/test/core/directive_lifecycle_integration_spec.ts b/modules/angular2/test/core/directive_lifecycle_integration_spec.ts index 013b408f57..9ae428ff62 100644 --- a/modules/angular2/test/core/directive_lifecycle_integration_spec.ts +++ b/modules/angular2/test/core/directive_lifecycle_integration_spec.ts @@ -9,6 +9,7 @@ import { it, xdescribe, xit, + Log, TestComponentBuilder } from 'angular2/test_lib'; @@ -18,28 +19,26 @@ export function main() { describe('directive lifecycle integration spec', () => { it('should invoke lifecycle methods onChanges > onInit > doCheck > afterContentChecked', - inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => { + inject([TestComponentBuilder, Log, AsyncTestCompleter], (tcb: TestComponentBuilder, log: Log, + async) => { tcb.overrideView( MyComp, new ViewMetadata( - {template: '
', directives: [LifecycleDir]})) + {template: '
', directives: [LifecycleCmp]})) .createAsync(MyComp) .then((tc) => { - var dir = tc.componentViewChildren[0].inject(LifecycleDir); tc.detectChanges(); - expect(dir.log).toEqual(["onChanges", "onInit", "doCheck", "afterContentChecked"]); + expect(log.result()) + .toEqual( + "onChanges; onInit; doCheck; afterContentInit; afterContentChecked; child_doCheck; " + + "afterViewInit; afterViewChecked"); + log.clear(); tc.detectChanges(); - expect(dir.log).toEqual([ - "onChanges", - "onInit", - "doCheck", - "afterContentChecked", - "doCheck", - "afterContentChecked" - ]); + expect(log.result()) + .toEqual("doCheck; afterContentChecked; child_doCheck; afterViewChecked"); async.done(); }); @@ -48,29 +47,43 @@ export function main() { } -@Directive({ +@Directive({selector: '[lifecycle-dir]', lifecycle: [LifecycleEvent.DoCheck]}) +class LifecycleDir { + constructor(private log: Log) {} + doCheck() { this.log.add("child_doCheck"); } +} + +@Component({ selector: "[lifecycle]", properties: ['field'], lifecycle: [ LifecycleEvent.OnChanges, - LifecycleEvent.DoCheck, LifecycleEvent.OnInit, - LifecycleEvent.AfterContentChecked + LifecycleEvent.DoCheck, + LifecycleEvent.AfterContentInit, + LifecycleEvent.AfterContentChecked, + LifecycleEvent.AfterViewInit, + LifecycleEvent.AfterViewChecked ] }) -class LifecycleDir { +@View({template: `
`, directives: [LifecycleDir]}) +class LifecycleCmp { field; - log: List; + constructor(private log: Log) {} - constructor() { this.log = []; } + onChanges(_) { this.log.add("onChanges"); } - onChanges(_) { this.log.push("onChanges"); } + onInit() { this.log.add("onInit"); } - onInit() { this.log.push("onInit"); } + doCheck() { this.log.add("doCheck"); } - doCheck() { this.log.push("doCheck"); } + afterContentInit() { this.log.add("afterContentInit"); } - afterContentChecked() { this.log.push("afterContentChecked"); } + afterContentChecked() { this.log.add("afterContentChecked"); } + + afterViewInit() { this.log.add("afterViewInit"); } + + afterViewChecked() { this.log.add("afterViewChecked"); } } @Component({selector: 'my-comp'}) diff --git a/modules/benchmarks/src/change_detection/change_detection_benchmark.ts b/modules/benchmarks/src/change_detection/change_detection_benchmark.ts index d2ba4f6027..2ef47037c6 100644 --- a/modules/benchmarks/src/change_detection/change_detection_benchmark.ts +++ b/modules/benchmarks/src/change_detection/change_detection_benchmark.ts @@ -389,4 +389,5 @@ class DummyDispatcher implements ChangeDispatcher { notifyOnBinding(bindingTarget, newValue) { throw "Should not be used"; } logBindingUpdate(bindingTarget, newValue) { throw "Should not be used"; } notifyAfterContentChecked() {} + notifyAfterViewChecked() {} } diff --git a/modules_dart/transform/lib/src/transform/common/convert.dart b/modules_dart/transform/lib/src/transform/common/convert.dart index ae2338cd26..7ff94c31ed 100644 --- a/modules_dart/transform/lib/src/transform/common/convert.dart +++ b/modules_dart/transform/lib/src/transform/common/convert.dart @@ -27,7 +27,10 @@ Map directiveMetadataToMap(RenderDirectiveMetadata meta) { ["callDoCheck", meta.callDoCheck], ["callOnInit", meta.callOnInit], ["callOnChanges", meta.callOnChanges], + ["callAfterContentInit", meta.callAfterContentInit], ["callAfterContentChecked", meta.callAfterContentChecked], + ["callAfterViewInit", meta.callAfterViewInit], + ["callAfterViewChecked", meta.callAfterViewChecked], ["events", meta.events], ["changeDetection", meta.changeDetection == null ? null : meta.changeDetection.index], ["version", 1] @@ -57,7 +60,10 @@ RenderDirectiveMetadata directiveMetadataFromMap(Map map) { callDoCheck: (map["callDoCheck"] as bool), callOnChanges: (map["callOnChanges"] as bool), callOnInit: (map["callOnInit"] as bool), + callAfterContentInit: (map["callAfterContentInit"] as bool), callAfterContentChecked: (map["callAfterContentChecked"] as bool), + callAfterViewInit: (map["callAfterViewInit"] as bool), + callAfterViewChecked: (map["callAfterViewChecked"] as bool), events: (_cloneIfPresent(map["events"]) as List), changeDetection: map["changeDetection"] == null ? null : ChangeDetectionStrategy.values[map["changeDetection"] as int]); diff --git a/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart b/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart index a37da00a07..5195352729 100644 --- a/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart +++ b/modules_dart/transform/lib/src/transform/common/directive_metadata_reader.dart @@ -63,7 +63,10 @@ class _DirectiveMetadataVisitor extends Object bool _callOnChange; bool _callOnCheck; bool _callOnInit; + bool _callAfterContentInit; bool _callAfterContentChecked; + bool _callAfterViewInit; + bool _callAfterViewChecked; ChangeDetectionStrategy _changeDetection; List _events; @@ -83,7 +86,10 @@ class _DirectiveMetadataVisitor extends Object _callOnChange = false; _callOnCheck = false; _callOnInit = false; + _callAfterContentInit = false; _callAfterContentChecked = false; + _callAfterViewInit = false; + _callAfterViewChecked = false; _changeDetection = null; _events = []; } @@ -100,7 +106,10 @@ class _DirectiveMetadataVisitor extends Object callOnChanges: _callOnChange, callDoCheck: _callOnCheck, callOnInit: _callOnInit, + callAfterContentInit: _callAfterContentInit, callAfterContentChecked: _callAfterContentChecked, + callAfterViewInit: _callAfterViewInit, + callAfterViewChecked: _callAfterViewChecked, changeDetection: _changeDetection, events: _events); @@ -274,7 +283,10 @@ class _DirectiveMetadataVisitor extends Object _callOnChange = lifecycleEvents.contains("OnChanges"); _callOnCheck = lifecycleEvents.contains("DoCheck"); _callOnInit = lifecycleEvents.contains("OnInit"); + _callAfterContentInit = lifecycleEvents.contains("AfterContentInit"); _callAfterContentChecked = lifecycleEvents.contains("AfterContentChecked"); + _callAfterViewInit = lifecycleEvents.contains("AfterViewInit"); + _callAfterViewChecked = lifecycleEvents.contains("AfterViewChecked"); } void _populateEvents(Expression eventsValue) { diff --git a/modules_dart/transform/lib/src/transform/common/interface_matcher.dart b/modules_dart/transform/lib/src/transform/common/interface_matcher.dart index c996e1ad75..4e82349466 100644 --- a/modules_dart/transform/lib/src/transform/common/interface_matcher.dart +++ b/modules_dart/transform/lib/src/transform/common/interface_matcher.dart @@ -33,13 +33,34 @@ const _ON_INIT_INTERFACES = const [ const ClassDescriptor( 'OnInit', 'package:angular2/src/core/compiler/interfaces.dart'), ]; -const _ON_ALL_CHANGES_DONE_INTERFACES = const [ +const _ON_AFTER_CONTENT_INIT_INTERFACES = const [ + const ClassDescriptor('AfterContentInit', 'package:angular2/angular2.dart'), + const ClassDescriptor( + 'AfterContentInit', 'package:angular2/metadata.dart'), + const ClassDescriptor( + 'AfterContentInit', 'package:angular2/src/core/compiler/interfaces.dart') +]; +const _ON_AFTER_CONTENT_CHECKED_INTERFACES = const [ const ClassDescriptor('AfterContentChecked', 'package:angular2/angular2.dart'), const ClassDescriptor( 'AfterContentChecked', 'package:angular2/metadata.dart'), const ClassDescriptor( 'AfterContentChecked', 'package:angular2/src/core/compiler/interfaces.dart') ]; +const _ON_AFTER_VIEW_INIT_INTERFACES = const [ + const ClassDescriptor('AfterViewInit', 'package:angular2/angular2.dart'), + const ClassDescriptor( + 'AfterViewInit', 'package:angular2/metadata.dart'), + const ClassDescriptor( + 'AfterViewInit', 'package:angular2/src/core/compiler/interfaces.dart') +]; +const _ON_AFTER_VIEW_CHECKED_INTERFACES = const [ + const ClassDescriptor('AfterViewChecked', 'package:angular2/angular2.dart'), + const ClassDescriptor( + 'AfterViewChecked', 'package:angular2/metadata.dart'), + const ClassDescriptor( + 'AfterViewChecked', 'package:angular2/src/core/compiler/interfaces.dart') +]; /// Checks if a given [Annotation] matches any of the given /// [ClassDescriptors]. @@ -52,7 +73,10 @@ class InterfaceMatcher extends ClassMatcherBase { ..addAll(_ON_DESTROY_INTERFACES) ..addAll(_ON_CHECK_INTERFACES) ..addAll(_ON_INIT_INTERFACES) - ..addAll(_ON_ALL_CHANGES_DONE_INTERFACES)); + ..addAll(_ON_AFTER_CONTENT_INIT_INTERFACES) + ..addAll(_ON_AFTER_CONTENT_CHECKED_INTERFACES) + ..addAll(_ON_AFTER_VIEW_INIT_INTERFACES) + ..addAll(_ON_AFTER_VIEW_CHECKED_INTERFACES)); } /// Checks if an [Identifier] implements [OnChanges]. @@ -71,7 +95,19 @@ class InterfaceMatcher extends ClassMatcherBase { bool isOnInit(Identifier typeName, AssetId assetId) => implements(firstMatch(typeName, assetId), _ON_INIT_INTERFACES); + /// Checks if an [Identifier] implements [AfterContentInit]. + bool isAfterContentInit(Identifier typeName, AssetId assetId) => implements( + firstMatch(typeName, assetId), _ON_AFTER_CONTENT_INIT_INTERFACES); + /// Checks if an [Identifier] implements [AfterContentChecked]. bool isAfterContentChecked(Identifier typeName, AssetId assetId) => implements( - firstMatch(typeName, assetId), _ON_ALL_CHANGES_DONE_INTERFACES); + firstMatch(typeName, assetId), _ON_AFTER_CONTENT_CHECKED_INTERFACES); + + /// Checks if an [Identifier] implements [AfterViewInit]. + bool isAfterViewInit(Identifier typeName, AssetId assetId) => implements( + firstMatch(typeName, assetId), _ON_AFTER_VIEW_INIT_INTERFACES); + + /// Checks if an [Identifier] implements [AfterViewChecked]. + bool isAfterViewChecked(Identifier typeName, AssetId assetId) => implements( + firstMatch(typeName, assetId), _ON_AFTER_VIEW_CHECKED_INTERFACES); } diff --git a/modules_dart/transform/lib/src/transform/directive_processor/visitors.dart b/modules_dart/transform/lib/src/transform/directive_processor/visitors.dart index 8f0ec973ee..c7859240d9 100644 --- a/modules_dart/transform/lib/src/transform/directive_processor/visitors.dart +++ b/modules_dart/transform/lib/src/transform/directive_processor/visitors.dart @@ -271,10 +271,22 @@ class AnnotationsTransformVisitor extends ToSourceVisitor { _ifaceLifecycleEntries.add('${LifecycleEvent.OnInit}'); populateImport(name); } + if (_interfaceMatcher.isAfterContentInit(name, _assetId)) { + _ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentInit}'); + populateImport(name); + } if (_interfaceMatcher.isAfterContentChecked(name, _assetId)) { _ifaceLifecycleEntries.add('${LifecycleEvent.AfterContentChecked}'); populateImport(name); } + if (_interfaceMatcher.isAfterViewInit(name, _assetId)) { + _ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewInit}'); + populateImport(name); + } + if (_interfaceMatcher.isAfterViewChecked(name, _assetId)) { + _ifaceLifecycleEntries.add('${LifecycleEvent.AfterViewChecked}'); + populateImport(name); + } }); } diff --git a/modules_dart/transform/lib/src/transform/template_compiler/change_detector_codegen.dart b/modules_dart/transform/lib/src/transform/template_compiler/change_detector_codegen.dart index b9aee1bb0a..597be85eff 100644 --- a/modules_dart/transform/lib/src/transform/template_compiler/change_detector_codegen.dart +++ b/modules_dart/transform/lib/src/transform/template_compiler/change_detector_codegen.dart @@ -143,15 +143,15 @@ class _CodegenState { var $_CHANGES_LOCAL = null; ${_records.map(_genRecord).join('')} - - ${_names.getAlreadyCheckedName()} = true; } ${_maybeGenHandleEventInternal()} ${_genCheckNoChanges()} - ${_maybeGenCallAfterContentChecked()} + ${_maybeGenAfterContentLifecycleCallbacks()} + + ${_maybeGenAfterViewLifecycleCallbacks()} ${_maybeGenHydrateDirectives()} @@ -260,19 +260,24 @@ class _CodegenState { '{ $hydrateDirectivesCode $hydrateDetectorsCode }'; } - /// Generates calls to `afterContentChecked` for all `Directive`s that request - /// them. - String _maybeGenCallAfterContentChecked() { - // NOTE(kegluneq): Order is important! - var directiveNotifications = _directiveRecords.reversed - .where((rec) => rec.callAfterContentChecked) - .map((rec) => - '${_names.getDirectiveName(rec.directiveIndex)}.afterContentChecked();'); - + String _maybeGenAfterContentLifecycleCallbacks() { + var directiveNotifications = _logic.genContentLifecycleCallbacks(_directiveRecords); if (directiveNotifications.isNotEmpty) { return ''' - void callAfterContentChecked() { - ${_names.getDispatcherName()}.notifyAfterContentChecked(); + void afterContentLifecycleCallbacksInternal() { + ${directiveNotifications.join('')} + } + '''; + } else { + return ''; + } + } + + String _maybeGenAfterViewLifecycleCallbacks() { + var directiveNotifications = _logic.genViewLifecycleCallbacks(_directiveRecords); + if (directiveNotifications.isNotEmpty) { + return ''' + void afterViewLifecycleCallbacksInternal() { ${directiveNotifications.join('')} } '''; diff --git a/modules_dart/transform/test/transform/common/convert_spec.dart b/modules_dart/transform/test/transform/common/convert_spec.dart index 030acb2c9f..4117bc732a 100644 --- a/modules_dart/transform/test/transform/common/convert_spec.dart +++ b/modules_dart/transform/test/transform/common/convert_spec.dart @@ -26,7 +26,10 @@ main() { callOnChanges: true, callDoCheck: true, callOnInit: true, + callAfterContentInit: true, callAfterContentChecked: true, + callAfterViewInit: true, + callAfterViewChecked: true, events: ["onFoo", "onBar"], changeDetection: ChangeDetectionStrategy.CheckOnce); var map = directiveMetadataToMap(someComponent); @@ -46,7 +49,10 @@ main() { expect(map["callDoCheck"]).toEqual(true); expect(map["callOnChanges"]).toEqual(true); expect(map["callOnInit"]).toEqual(true); + expect(map["callAfterContentInit"]).toEqual(true); expect(map["callAfterContentChecked"]).toEqual(true); + expect(map["callAfterViewInit"]).toEqual(true); + expect(map["callAfterViewChecked"]).toEqual(true); expect(map["exportAs"]).toEqual("aaa"); expect(map["events"]).toEqual(["onFoo", "onBar"]); expect(map["changeDetection"]).toEqual(ChangeDetectionStrategy.CheckOnce.index); @@ -67,7 +73,10 @@ main() { ["callDoCheck", true], ["callOnInit", true], ["callOnChanges", true], + ["callAfterContentInit", true], ["callAfterContentChecked", true], + ["callAfterViewInit", true], + ["callAfterViewChecked", true], ["events", ["onFoo", "onBar"]], ["changeDetection", ChangeDetectionStrategy.CheckOnce.index] ]); @@ -89,7 +98,10 @@ main() { expect(meta.callDoCheck).toEqual(true); expect(meta.callOnInit).toEqual(true); expect(meta.callOnChanges).toEqual(true); + expect(meta.callAfterContentInit).toEqual(true); expect(meta.callAfterContentChecked).toEqual(true); + expect(meta.callAfterViewInit).toEqual(true); + expect(meta.callAfterViewChecked).toEqual(true); expect(meta.events).toEqual(["onFoo", "onBar"]); expect(meta.changeDetection).toEqual(ChangeDetectionStrategy.CheckOnce); }); diff --git a/modules_dart/transform/test/transform/directive_metadata_extractor/all_tests.dart b/modules_dart/transform/test/transform/directive_metadata_extractor/all_tests.dart index 0d7ec87edb..c1831108e2 100644 --- a/modules_dart/transform/test/transform/directive_metadata_extractor/all_tests.dart +++ b/modules_dart/transform/test/transform/directive_metadata_extractor/all_tests.dart @@ -106,7 +106,10 @@ void allTests() { expect(metadata.callOnChanges).toBe(true); expect(metadata.callDoCheck).toBe(true); expect(metadata.callOnInit).toBe(true); + expect(metadata.callAfterContentInit).toBe(true); expect(metadata.callAfterContentChecked).toBe(true); + expect(metadata.callAfterViewInit).toBe(true); + expect(metadata.callAfterViewChecked).toBe(true); }); it('should parse events.', () async { diff --git a/modules_dart/transform/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart b/modules_dart/transform/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart index 3d6bbca6d3..ea6f680c0c 100644 --- a/modules_dart/transform/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart +++ b/modules_dart/transform/test/transform/directive_metadata_extractor/directive_metadata_files/lifecycle.ng_deps.dart @@ -17,7 +17,10 @@ void initReflector(reflector) { LifecycleEvent.OnDestroy, LifecycleEvent.OnInit, LifecycleEvent.DoCheck, - LifecycleEvent.AfterContentChecked + LifecycleEvent.AfterContentInit, + LifecycleEvent.AfterContentChecked, + LifecycleEvent.AfterViewInit, + LifecycleEvent.AfterViewChecked ]) ], const [ const [] diff --git a/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/expected/soup.ng_deps.dart b/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/expected/soup.ng_deps.dart index fd7851bd97..79f777d22a 100644 --- a/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/expected/soup.ng_deps.dart +++ b/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/expected/soup.ng_deps.dart @@ -52,6 +52,17 @@ void initReflector() { const [], () => new OnInitSoupComponent(), const [OnInit])) + ..registerType( + AfterContentInitSoupComponent, + new _ngRef.ReflectionInfo( + const [ + const Component( + selector: '[soup]', + lifecycle: const [LifecycleEvent.AfterContentInit]) + ], + const [], + () => new AfterContentInitSoupComponent(), + const [AfterContentInit])) ..registerType( AfterContentCheckedSoupComponent, new _ngRef.ReflectionInfo( @@ -62,5 +73,27 @@ void initReflector() { ], const [], () => new AfterContentCheckedSoupComponent(), - const [AfterContentChecked])); + const [AfterContentChecked])) + ..registerType( + AfterViewInitSoupComponent, + new _ngRef.ReflectionInfo( + const [ + const Component( + selector: '[soup]', + lifecycle: const [LifecycleEvent.AfterViewInit]) + ], + const [], + () => new AfterViewInitSoupComponent(), + const [AfterViewInit])) + ..registerType( + AfterViewCheckedSoupComponent, + new _ngRef.ReflectionInfo( + const [ + const Component( + selector: '[soup]', + lifecycle: const [LifecycleEvent.AfterViewChecked]) + ], + const [], + () => new AfterViewCheckedSoupComponent(), + const [AfterViewChecked])); } diff --git a/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/soup.dart b/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/soup.dart index 04c890c2cd..f249749fd4 100644 --- a/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/soup.dart +++ b/modules_dart/transform/test/transform/directive_processor/interface_lifecycle_files/soup.dart @@ -14,5 +14,14 @@ class OnCheckSoupComponent implements DoCheck {} @Component(selector: '[soup]') class OnInitSoupComponent implements OnInit {} +@Component(selector: '[soup]') +class AfterContentInitSoupComponent implements AfterContentInit {} + @Component(selector: '[soup]') class AfterContentCheckedSoupComponent implements AfterContentChecked {} + +@Component(selector: '[soup]') +class AfterViewInitSoupComponent implements AfterViewInit {} + +@Component(selector: '[soup]') +class AfterViewCheckedSoupComponent implements AfterViewChecked {} \ No newline at end of file diff --git a/modules_dart/transform/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json b/modules_dart/transform/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json index 5c32ed4d44..abeb23a1f8 100644 --- a/modules_dart/transform/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json +++ b/modules_dart/transform/test/transform/integration/simple_annotation_files/expected/bar.ng_meta.json @@ -16,7 +16,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 diff --git a/modules_dart/transform/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart b/modules_dart/transform/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart index 32b11c8597..e3a153f8e9 100644 --- a/modules_dart/transform/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart +++ b/modules_dart/transform/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart @@ -66,8 +66,6 @@ class _MyComponent_ChangeDetector0 changes = null; isChanged = false; - - this.alreadyChecked = true; } void checkNoChanges() { diff --git a/modules_dart/transform/test/transform/template_compiler/registrations_files/dependency.ng_meta.json b/modules_dart/transform/test/transform/template_compiler/registrations_files/dependency.ng_meta.json index a1e24952a8..5889d17979 100644 --- a/modules_dart/transform/test/transform/template_compiler/registrations_files/dependency.ng_meta.json +++ b/modules_dart/transform/test/transform/template_compiler/registrations_files/dependency.ng_meta.json @@ -16,7 +16,10 @@ "callDoCheck": null, "callOnInit": null, "callOnChanges": null, + "callAfterContentInit": null, "callAfterContentChecked": null, + "callAfterViewInit": null, + "callAfterViewChecked": null, "events": ["dependencyEventName"], "changeDetection": null, "version": 1 @@ -39,7 +42,10 @@ "callDoCheck": null, "callOnInit": null, "callOnChanges": null, + "callAfterContentInit": null, "callAfterContentChecked": null, + "callAfterViewInit": null, + "callAfterViewChecked": null, "events": null, "changeDetection": null, "version": 1 @@ -62,7 +68,10 @@ "callDoCheck": null, "callOnInit": null, "callOnChanges": null, + "callAfterContentInit": null, "callAfterContentChecked": null, + "callAfterViewInit": null, + "callAfterViewChecked": null, "events": null, "changeDetection": null, "version": 1 @@ -85,7 +94,10 @@ "callDoCheck": true, "callOnInit": null, "callOnChanges": null, + "callAfterContentInit": null, "callAfterContentChecked": null, + "callAfterViewInit": null, + "callAfterViewChecked": null, "events": null, "changeDetection": null, "version": 1 diff --git a/modules_dart/transform/test/transform/template_compiler/registrations_files/registrations.ng_meta.json b/modules_dart/transform/test/transform/template_compiler/registrations_files/registrations.ng_meta.json index ddde7cb774..4a30d37f56 100644 --- a/modules_dart/transform/test/transform/template_compiler/registrations_files/registrations.ng_meta.json +++ b/modules_dart/transform/test/transform/template_compiler/registrations_files/registrations.ng_meta.json @@ -16,7 +16,10 @@ "callDoCheck": null, "callOnInit": null, "callOnChanges": null, + "callAfterContentInit": null, "callAfterContentChecked": null, + "callAfterViewInit": null, + "callAfterViewChecked": null, "events": null, "changeDetection": null, "version": 1 @@ -39,7 +42,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 @@ -62,7 +68,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": ["eventName"], "changeDetection": null, "version": 1 @@ -85,7 +94,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 @@ -108,7 +120,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 @@ -131,7 +146,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 @@ -154,7 +172,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1 @@ -177,7 +198,10 @@ "callDoCheck": false, "callOnInit": false, "callOnChanges": false, + "callAfterContentInit": false, "callAfterContentChecked": false, + "callAfterViewInit": false, + "callAfterViewChecked": false, "events": [], "changeDetection": null, "version": 1