diff --git a/modules/angular2/src/core/annotations_impl/annotations.ts b/modules/angular2/src/core/annotations_impl/annotations.ts index 7e32907cc8..bcc2ce96fe 100644 --- a/modules/angular2/src/core/annotations_impl/annotations.ts +++ b/modules/angular2/src/core/annotations_impl/annotations.ts @@ -550,7 +550,7 @@ export class Directive extends Injectable { * events: ['statusChange'] * }) * class TaskComponent { - * statusChange:EventEmitter; + * statusChange: EventEmitter; * * constructor() { * this.statusChange = new EventEmitter(); @@ -561,6 +561,26 @@ export class Directive extends Injectable { * } * } * ``` + * + * Use `propertyName: eventName` when the event emitter property name is different from the name + * of the emitted event: + * + * @Component({ + * events: ['status: statusChange'] + * }) + * class TaskComponent { + * status: EventEmitter; + * + * constructor() { + * this.status = new EventEmitter(); + * } + * + * onComplete() { + * this.status.next('completed'); + * } + * } + * ``` + * */ events: List; diff --git a/modules/angular2/src/core/compiler/element_injector.ts b/modules/angular2/src/core/compiler/element_injector.ts index 1ddc95dcc8..20a42d4793 100644 --- a/modules/angular2/src/core/compiler/element_injector.ts +++ b/modules/angular2/src/core/compiler/element_injector.ts @@ -4,7 +4,8 @@ import { Type, BaseException, stringify, - CONST_EXPR + CONST_EXPR, + StringWrapper } from 'angular2/src/facade/lang'; import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; @@ -382,8 +383,20 @@ export class BindingData { createEventEmitterAccessors() { if (!(this.binding instanceof DirectiveBinding)) return []; var db = this.binding; - return ListWrapper.map(db.eventEmitters, eventName => new EventEmitterAccessor( - eventName, reflector.getter(eventName))); + return ListWrapper.map(db.eventEmitters, eventConfig => { + let fieldName; + let eventName; + var colonIdx = eventConfig.indexOf(':'); + if (colonIdx > -1) { + // long format: 'fieldName: eventName' + fieldName = StringWrapper.substring(eventConfig, 0, colonIdx).trim(); + eventName = StringWrapper.substring(eventConfig, colonIdx + 1).trim(); + } else { + // short format: 'name' when fieldName and eventName are the same + fieldName = eventName = eventConfig; + } + return new EventEmitterAccessor(eventName, reflector.getter(fieldName)) + }); } createHostActionAccessors() { diff --git a/modules/angular2/test/core/compiler/element_injector_spec.ts b/modules/angular2/test/core/compiler/element_injector_spec.ts index d95dbf065e..7231514e77 100644 --- a/modules/angular2/test/core/compiler/element_injector_spec.ts +++ b/modules/angular2/test/core/compiler/element_injector_spec.ts @@ -418,6 +418,18 @@ export function main() { expect(accessor.getter(new HasEventEmitter())).toEqual('emitter'); }); + it('should allow a different event vs field name', () => { + var binding = DirectiveBinding.createFromType(HasEventEmitter, + new dirAnn.Directive({events: ['emitter: publicEmitter']})); + + var inj = createPei(null, 0, [binding]); + expect(inj.eventEmitterAccessors.length).toEqual(1); + + var accessor = inj.eventEmitterAccessors[0][0]; + expect(accessor.eventName).toEqual('publicEmitter'); + expect(accessor.getter(new HasEventEmitter())).toEqual('emitter'); + }); + it('should return a list of hostAction accessors', () => { var binding = DirectiveBinding.createFromType( HasEventEmitter, new dirAnn.Directive({hostActions: {'hostActionName': 'onAction'}})); @@ -431,7 +443,6 @@ export function main() { }); }); - describe(".create", () => { it("should collect hostInjector injectables from all directives", () => { var pei = createPei(null, 0, [