Skip to content

Commit ae30d7b

Browse files
fix(di): allow injecting event emitter fns without specifying type annotation
Fixes angular#965 Closes angular#1155
1 parent 9adf41c commit ae30d7b

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

modules/angular2/src/core/annotations/di.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ export class EventEmitter extends DependencyAnnotation {
1212
super();
1313
this.eventName = eventName;
1414
}
15+
16+
get token() {
17+
return Function;
18+
}
1519
}
1620

1721
/**
@@ -25,6 +29,10 @@ export class PropertySetter extends DependencyAnnotation {
2529
super();
2630
this.propName = propName;
2731
}
32+
33+
get token() {
34+
return Function;
35+
}
2836
}
2937

3038
/**

modules/angular2/src/di/annotations.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export class DependencyAnnotation {
107107
@CONST()
108108
constructor() {
109109
}
110+
111+
get token() {
112+
return null;
113+
}
110114
}
111115

112116
/**

modules/angular2/src/di/binding.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ function _extractToken(typeOrFunc, annotations) {
135135
optional = true;
136136

137137
} else if (paramAnnotation instanceof DependencyAnnotation) {
138+
if (isPresent(paramAnnotation.token)) {
139+
token = paramAnnotation.token;
140+
}
138141
ListWrapper.push(depProps, paramAnnotation);
142+
139143
} else if (paramAnnotation.name === "string") {
140144
token = paramAnnotation;
141145
}

modules/angular2/test/core/compiler/element_injector_spec.js

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ class NeedsEventEmitter {
7979
}
8080
}
8181

82+
class NeedsEventEmitterNoType {
83+
clickEmitter;
84+
constructor(@EventEmitter('click') clickEmitter) {
85+
this.clickEmitter = clickEmitter;
86+
}
87+
click() {
88+
this.clickEmitter(null);
89+
}
90+
}
91+
8292
class NeedsPropertySetter {
8393
propSetter;
8494
roleSetter;
@@ -113,6 +123,17 @@ class NeedsPropertySetter {
113123
}
114124
}
115125

126+
class NeedsPropertySetterNoType {
127+
propSetter;
128+
constructor(@PropertySetter('title') propSetter) {
129+
this.propSetter = propSetter;
130+
}
131+
132+
setProp(value) {
133+
this.propSetter(value);
134+
}
135+
}
136+
116137
class NeedsAttribute {
117138
typeAttribute;
118139
titleAttribute;
@@ -545,24 +566,43 @@ export function main() {
545566
});
546567

547568
describe('event emitters', () => {
548-
it('should be injectable and callable', () => {
549-
var called = false;
569+
570+
function createpreBuildObject(eventName, eventHandler) {
550571
var handlers = StringMapWrapper.create();
551-
StringMapWrapper.set(handlers, 'click', (e, view) => { called = true;});
572+
StringMapWrapper.set(handlers, eventName, eventHandler);
552573
var pv = new ProtoView(null, null, null);
553574
pv.eventHandlers = [handlers];
554575
var view = new View(pv, null, MapWrapper.create());
555-
var preBuildObject = new PreBuiltObjects(view, null, null, null);
576+
return new PreBuiltObjects(view, null, null, null);
577+
}
578+
579+
it('should be injectable and callable', () => {
580+
var called = false;
581+
var preBuildObject = createpreBuildObject('click', (e, view) => { called = true;});
556582
var inj = injector([NeedsEventEmitter], null, null, preBuildObject);
557583
inj.get(NeedsEventEmitter).click();
558584
expect(called).toEqual(true);
559585
});
560586

587+
it('should be injectable and callable without specifying param type annotation', () => {
588+
var called = false;
589+
var preBuildObject = createpreBuildObject('click', (e, view) => { called = true;});
590+
var inj = injector([NeedsEventEmitterNoType], null, null, preBuildObject);
591+
inj.get(NeedsEventEmitterNoType).click();
592+
expect(called).toEqual(true);
593+
});
594+
561595
it('should be queryable through hasEventEmitter', () => {
562596
var inj = injector([NeedsEventEmitter]);
563597
expect(inj.hasEventEmitter('click')).toBe(true);
564598
expect(inj.hasEventEmitter('move')).toBe(false);
565599
});
600+
601+
it('should be queryable through hasEventEmitter without specifying param type annotation', () => {
602+
var inj = injector([NeedsEventEmitterNoType]);
603+
expect(inj.hasEventEmitter('click')).toBe(true);
604+
expect(inj.hasEventEmitter('move')).toBe(false);
605+
});
566606
});
567607

568608
describe('property setter', () => {
@@ -577,7 +617,7 @@ export function main() {
577617
component.setRole('button');
578618
component.setClass(true);
579619
component.classWithDashSetter(true);
580-
component.setStyle('40px')
620+
component.setStyle('40px');
581621
component.setStyleWithUnit(50);
582622

583623
expect(div.title).toEqual('foobar');
@@ -587,6 +627,16 @@ export function main() {
587627
expect(DOM.getStyle(div, 'width')).toEqual('40px');
588628
expect(DOM.getStyle(div, 'height')).toEqual('50px');
589629
});
630+
631+
it('should be injectable and callable without specifying param type annotation', () => {
632+
var div = el('<div></div>');
633+
var preBuildObject = new PreBuiltObjects(null, new NgElement(div), null, null);
634+
var inj = injector([NeedsPropertySetterNoType], null, null, preBuildObject);
635+
var component = inj.get(NeedsPropertySetterNoType);
636+
component.setProp('foobar');
637+
638+
expect(div.title).toEqual('foobar');
639+
});
590640
});
591641

592642
describe('static', () => {

0 commit comments

Comments
 (0)