diff --git a/modules/@angular/compiler/src/directive_wrapper_compiler.ts b/modules/@angular/compiler/src/directive_wrapper_compiler.ts index 00729fe3c7..4a27901680 100644 --- a/modules/@angular/compiler/src/directive_wrapper_compiler.ts +++ b/modules/@angular/compiler/src/directive_wrapper_compiler.ts @@ -29,9 +29,9 @@ export class DirectiveWrapperCompileResult { } const CONTEXT_FIELD_NAME = 'context'; -const CHANGES_FIELD_NAME = 'changes'; -const CHANGED_FIELD_NAME = 'changed'; -const EVENT_HANDLER_FIELD_NAME = 'eventHandler'; +const CHANGES_FIELD_NAME = '_changes'; +const CHANGED_FIELD_NAME = '_changed'; +const EVENT_HANDLER_FIELD_NAME = '_eventHandler'; const CURR_VALUE_VAR = o.variable('currValue'); const THROW_ON_CHANGE_VAR = o.variable('throwOnChange'); @@ -129,14 +129,15 @@ class DirectiveWrapperBuilder implements ClassBuilder { const fields: o.ClassField[] = [ - new o.ClassField(EVENT_HANDLER_FIELD_NAME, o.FUNCTION_TYPE), + new o.ClassField(EVENT_HANDLER_FIELD_NAME, o.FUNCTION_TYPE, [o.StmtModifier.Private]), new o.ClassField(CONTEXT_FIELD_NAME, o.importType(this.dirMeta.type)), - new o.ClassField(CHANGED_FIELD_NAME, o.BOOL_TYPE), + new o.ClassField(CHANGED_FIELD_NAME, o.BOOL_TYPE, [o.StmtModifier.Private]), ]; const ctorStmts: o.Statement[] = [o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(false)).toStmt()]; if (this.genChanges) { - fields.push(new o.ClassField(CHANGES_FIELD_NAME, new o.MapType(o.DYNAMIC_TYPE))); + fields.push(new o.ClassField( + CHANGES_FIELD_NAME, new o.MapType(o.DYNAMIC_TYPE), [o.StmtModifier.Private])); ctorStmts.push(RESET_CHANGES_STMT); } @@ -303,7 +304,11 @@ function addHandleEventMethod(hostListeners: BoundEventAst[], builder: Directive } function addSubscribeMethod(dirMeta: CompileDirectiveMetadata, builder: DirectiveWrapperBuilder) { - const methodParams: o.FnParam[] = [new o.FnParam(EVENT_HANDLER_FIELD_NAME, o.DYNAMIC_TYPE)]; + const methodParams: o.FnParam[] = [ + new o.FnParam( + VIEW_VAR.name, o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), + new o.FnParam(EVENT_HANDLER_FIELD_NAME, o.DYNAMIC_TYPE) + ]; const stmts: o.Statement[] = [ o.THIS_EXPR.prop(EVENT_HANDLER_FIELD_NAME).set(o.variable(EVENT_HANDLER_FIELD_NAME)).toStmt() ]; @@ -313,17 +318,16 @@ function addSubscribeMethod(dirMeta: CompileDirectiveMetadata, builder: Directiv methodParams.push(new o.FnParam(paramName, o.BOOL_TYPE)); const subscriptionFieldName = `subscription${emitterIdx}`; builder.fields.push(new o.ClassField(subscriptionFieldName, o.DYNAMIC_TYPE)); - stmts.push(new o.IfStmt( - o.variable(paramName), - [o.THIS_EXPR.prop(subscriptionFieldName) - .set(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME) - .prop(emitterPropName) - .callMethod( - o.BuiltinMethod.SubscribeObservable, - [o.variable(EVENT_HANDLER_FIELD_NAME) - .callMethod( - o.BuiltinMethod.Bind, [o.NULL_EXPR, o.literal(eventName)])])) - .toStmt()])); + stmts.push(new o.IfStmt(o.variable(paramName), [ + o.THIS_EXPR.prop(subscriptionFieldName) + .set(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME) + .prop(emitterPropName) + .callMethod( + o.BuiltinMethod.SubscribeObservable, + [o.variable(EVENT_HANDLER_FIELD_NAME) + .callMethod(o.BuiltinMethod.Bind, [VIEW_VAR, o.literal(eventName)])])) + .toStmt() + ])); builder.destroyStmts.push( o.THIS_EXPR.prop(subscriptionFieldName) .and(o.THIS_EXPR.prop(subscriptionFieldName).callMethod('unsubscribe', [])) @@ -424,7 +428,7 @@ export class DirectiveWrapperExpressions { } static subscribe( dirMeta: CompileDirectiveMetadata, hostProps: BoundElementPropertyAst[], usedEvents: string[], - dirWrapper: o.Expression, eventListener: o.Expression): o.Statement[] { + dirWrapper: o.Expression, view: o.Expression, eventListener: o.Expression): o.Statement[] { let needsSubscribe = false; let eventFlags: o.Expression[] = []; Object.keys(dirMeta.outputs).forEach((propName) => { @@ -439,7 +443,9 @@ export class DirectiveWrapperExpressions { } }); if (needsSubscribe) { - return [dirWrapper.callMethod('subscribe', [eventListener].concat(eventFlags)).toStmt()]; + return [ + dirWrapper.callMethod('subscribe', [view, eventListener].concat(eventFlags)).toStmt() + ]; } else { return []; } diff --git a/modules/@angular/compiler/src/view_compiler/event_binder.ts b/modules/@angular/compiler/src/view_compiler/event_binder.ts index 088bbedbcf..dde25b05cf 100644 --- a/modules/@angular/compiler/src/view_compiler/event_binder.ts +++ b/modules/@angular/compiler/src/view_compiler/event_binder.ts @@ -59,8 +59,8 @@ function subscribeToRenderEvents( compileElement.view.createMethod.addStmt( disposableVar .set(o.importExpr(resolveIdentifier(Identifiers.subscribeToRenderElement)).callFn([ - ViewProperties.renderer, compileElement.renderNode, - createInlineArray(eventAndTargetExprs), handleEventClosure(compileElement) + o.THIS_EXPR, compileElement.renderNode, createInlineArray(eventAndTargetExprs), + handleEventExpr(compileElement) ])) .toDeclStmt(o.FUNCTION_TYPE, [o.StmtModifier.Private])); } @@ -73,8 +73,8 @@ function subscribeToDirectiveEvents( directives.forEach((dirAst) => { const dirWrapper = compileElement.directiveWrapperInstance.get(dirAst.directive.type.reference); compileElement.view.createMethod.addStmts(DirectiveWrapperExpressions.subscribe( - dirAst.directive, dirAst.hostProperties, usedEventNames, dirWrapper, - handleEventClosure(compileElement))); + dirAst.directive, dirAst.hostProperties, usedEventNames, dirWrapper, o.THIS_EXPR, + handleEventExpr(compileElement))); }); } @@ -127,11 +127,9 @@ function generateHandleEventMethod( handleEventStmts.finish(), o.BOOL_TYPE)); } -function handleEventClosure(compileElement: CompileElement) { +function handleEventExpr(compileElement: CompileElement) { const handleEventMethodName = getHandleEventMethodName(compileElement.nodeIndex); - return o.THIS_EXPR.callMethod( - 'eventHandler', - [o.THIS_EXPR.prop(handleEventMethodName).callMethod(o.BuiltinMethod.Bind, [o.THIS_EXPR])]); + return o.THIS_EXPR.callMethod('eventHandler', [o.THIS_EXPR.prop(handleEventMethodName)]); } type EventSummary = { diff --git a/modules/@angular/core/src/linker/view.ts b/modules/@angular/core/src/linker/view.ts index b86a00d980..f9b3057784 100644 --- a/modules/@angular/core/src/linker/view.ts +++ b/modules/@angular/core/src/linker/view.ts @@ -375,7 +375,7 @@ export class DebugAppView extends AppView { return (eventName: string, event?: any) => { this._resetDebug(); try { - return superHandler(eventName, event); + return superHandler.call(this, eventName, event); } catch (e) { this._rethrowWithContext(e); throw e; diff --git a/modules/@angular/core/src/linker/view_utils.ts b/modules/@angular/core/src/linker/view_utils.ts index 44c3e49717..a88b17c4e8 100644 --- a/modules/@angular/core/src/linker/view_utils.ts +++ b/modules/@angular/core/src/linker/view_utils.ts @@ -17,6 +17,7 @@ import {Sanitizer} from '../security'; import {AppElement} from './element'; import {ExpressionChangedAfterItHasBeenCheckedError} from './errors'; +import {AppView} from './view'; @Injectable() export class ViewUtils { @@ -401,7 +402,7 @@ export function selectOrCreateRenderHostElement( } export function subscribeToRenderElement( - renderer: Renderer, element: any, eventNamesAndTargets: InlineArray, + view: AppView, element: any, eventNamesAndTargets: InlineArray, listener: (eventName: string, event: any) => any) { const disposables = createEmptyInlineArray(eventNamesAndTargets.length / 2); for (var i = 0; i < eventNamesAndTargets.length; i += 2) { @@ -409,10 +410,10 @@ export function subscribeToRenderElement( const eventTarget = eventNamesAndTargets.get(i + 1); let disposable: Function; if (eventTarget) { - disposable = renderer.listenGlobal( - eventTarget, eventName, listener.bind(null, `${eventTarget}:${eventName}`)); + disposable = view.renderer.listenGlobal( + eventTarget, eventName, listener.bind(view, `${eventTarget}:${eventName}`)); } else { - disposable = renderer.listen(element, eventName, listener.bind(null, eventName)); + disposable = view.renderer.listen(element, eventName, listener.bind(view, eventName)); } disposables.set(i / 2, disposable); }