diff --git a/modules/angular2/src/change_detection/change_detection_jit_generator.es6 b/modules/angular2/src/change_detection/change_detection_jit_generator.es6 index b612d5efa271..9ba4a302bee2 100644 --- a/modules/angular2/src/change_detection/change_detection_jit_generator.es6 +++ b/modules/angular2/src/change_detection/change_detection_jit_generator.es6 @@ -203,6 +203,17 @@ if (${TEMP_LOCAL} instanceof ContextWithVariableBindings) { `; } +function invokeMethodTemplate(name:string, args:string, context:string, newValue:string) { + return ` +${TEMP_LOCAL} = ${UTIL}.findContext("${name}", ${context}); +if (${TEMP_LOCAL} instanceof ContextWithVariableBindings) { + ${newValue} = ${TEMP_LOCAL}.get('${name}').apply(null, [${args}]); +} else { + ${newValue} = ${context}.${name}(${args}); +} +`; +} + function localDefinitionsTemplate(names:List):string { return names.map((n) => `var ${n};`).join("\n"); } @@ -366,7 +377,11 @@ export class ChangeDetectorJITGenerator { } case RECORD_TYPE_INVOKE_METHOD: - return assignmentTemplate(newValue, `${context}.${r.name}(${args})`); + if (r.contextIndex == 0) { // only the first property read can be a local + return invokeMethodTemplate(r.name, args, context, newValue); + } else { + return assignmentTemplate(newValue, `${context}.${r.name}(${args})`); + } case RECORD_TYPE_INVOKE_CLOSURE: return assignmentTemplate(newValue, `${context}(${args})`); diff --git a/modules/angular2/src/change_detection/dynamic_change_detector.js b/modules/angular2/src/change_detection/dynamic_change_detector.js index 8dee6b5e631e..051fb027fbfa 100644 --- a/modules/angular2/src/change_detection/dynamic_change_detector.js +++ b/modules/angular2/src/change_detection/dynamic_change_detector.js @@ -132,8 +132,16 @@ export class DynamicChangeDetector extends AbstractChangeDetector { break; case RECORD_TYPE_INVOKE_METHOD: - var methodInvoker:Function = proto.funcOrValue; - return methodInvoker(this._readContext(proto), this._readArgs(proto)); + var context = this._readContext(proto); + var args = this._readArgs(proto); + var c = ChangeDetectionUtil.findContext(proto.name, context); + if (c instanceof ContextWithVariableBindings) { + return FunctionWrapper.apply(c.get(proto.name), args); + } else { + var methodInvoker:Function = proto.funcOrValue; + return methodInvoker(c, args); + } + break; case RECORD_TYPE_KEYED_ACCESS: var arg = this._readArgs(proto)[0]; diff --git a/modules/angular2/test/change_detection/change_detection_spec.js b/modules/angular2/test/change_detection/change_detection_spec.js index c6f1d76f03b5..f2bc3f0edd46 100644 --- a/modules/angular2/test/change_detection/change_detection_spec.js +++ b/modules/angular2/test/change_detection/change_detection_spec.js @@ -318,6 +318,14 @@ export function main() { .toEqual(['key=value']); }); + it('should invoke a function from ContextWithVariableBindings', () => { + var locals = new ContextWithVariableBindings(null, + MapWrapper.createFromPairs([["key", () => "value"]])); + + expect(executeWatch('key', 'key()', locals)) + .toEqual(['key=value']); + }); + it('should handle nested ContextWithVariableBindings', () => { var nested = new ContextWithVariableBindings(null, MapWrapper.createFromPairs([["key", "value"]]));