X Tutup
Skip to content

Commit 3118d5c

Browse files
committed
fix(compiler): support events on a template element that are consumed via a direct expression
Closes #4883
1 parent 56a9b02 commit 3118d5c

File tree

6 files changed

+31
-10
lines changed

6 files changed

+31
-10
lines changed

modules/angular2/src/core/compiler/change_definition_factory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ProtoViewVisitor implements TemplateAstVisitor {
5858

5959
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {
6060
this.boundElementCount++;
61+
templateVisitAll(this, ast.outputs);
6162
for (var i = 0; i < ast.directives.length; i++) {
6263
ast.directives[i].visit(this, i);
6364
}

modules/angular2/src/core/compiler/template_ast.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class ElementAst implements TemplateAst {
7777
}
7878

7979
export class EmbeddedTemplateAst implements TemplateAst {
80-
constructor(public attrs: AttrAst[], public vars: VariableAst[],
80+
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
8181
public directives: DirectiveAst[], public children: TemplateAst[],
8282
public ngContentIndex: number, public sourceInfo: string) {}
8383
visit(visitor: TemplateAstVisitor, context: any): any {

modules/angular2/src/core/compiler/template_parser.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
223223
this._assertAllEventsPublishedByDirectives(directives, events, element.sourceInfo);
224224
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps,
225225
element.sourceInfo);
226-
parsedElement = new EmbeddedTemplateAst(attrs, vars, directives, children,
226+
parsedElement = new EmbeddedTemplateAst(attrs, events, vars, directives, children,
227227
elementNgContentIndex, element.sourceInfo);
228228
} else {
229229
this._assertOnlyOneComponent(directives, element.sourceInfo);
@@ -241,9 +241,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
241241
element.name, templateElementOrDirectiveProps, templateDirectives);
242242
this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectives, templateElementProps,
243243
element.sourceInfo);
244-
parsedElement = new EmbeddedTemplateAst([], templateVars, templateDirectives, [parsedElement],
245-
component.findNgContentIndex(templateCssSelector),
246-
element.sourceInfo);
244+
parsedElement = new EmbeddedTemplateAst(
245+
[], [], templateVars, templateDirectives, [parsedElement],
246+
component.findNgContentIndex(templateCssSelector), element.sourceInfo);
247247
}
248248
return parsedElement;
249249
}

modules/angular2/test/core/compiler/change_definition_factory_spec.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,28 @@ export function main() {
9090
expect(dispatcher.log).toEqual(['textNode(null)=someValue']);
9191
});
9292

93-
it('should handle events', () => {
93+
it('should handle events on regular elements', () => {
9494
var changeDetector = createChangeDetector('<div on-click="onEvent($event)">', [], 0);
9595

9696
eventLocals.set('$event', 'click');
9797
changeDetector.handleEvent('click', 0, eventLocals);
9898
expect(context.eventLog).toEqual(['click']);
9999
});
100100

101+
it('should handle events on template elements', () => {
102+
var dirMeta = CompileDirectiveMetadata.create({
103+
type: new CompileTypeMetadata({name: 'SomeDir'}),
104+
selector: 'template',
105+
outputs: ['click']
106+
});
107+
var changeDetector =
108+
createChangeDetector('<template on-click="onEvent($event)">', [dirMeta], 0);
109+
110+
eventLocals.set('$event', 'click');
111+
changeDetector.handleEvent('click', 0, eventLocals);
112+
expect(context.eventLog).toEqual(['click']);
113+
});
114+
101115
it('should handle events with targets', () => {
102116
var changeDetector = createChangeDetector('<div (window:click)="onEvent($event)">', [], 0);
103117

modules/angular2/test/core/compiler/template_parser_spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ export function main() {
277277
expect(humanizeTemplateAsts(parse('<template (e)="f"></template>', [dirA])))
278278
.toEqual([
279279
[EmbeddedTemplateAst, 'TestComp > template:nth-child(0)'],
280+
[BoundEventAst, 'e', null, 'f', 'TestComp > template:nth-child(0)[(e)=f]'],
280281
[DirectiveAst, dirA, 'TestComp > template:nth-child(0)'],
281282
]);
282283
});
@@ -978,6 +979,7 @@ class TemplateHumanizer implements TemplateAstVisitor {
978979
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {
979980
this.result.push([EmbeddedTemplateAst, ast.sourceInfo]);
980981
templateVisitAll(this, ast.attrs);
982+
templateVisitAll(this, ast.outputs);
981983
templateVisitAll(this, ast.vars);
982984
templateVisitAll(this, ast.directives);
983985
templateVisitAll(this, ast.children);

modules/angular2/test/core/linker/integration_spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -827,22 +827,26 @@ export function main() {
827827

828828
it('should support events via EventEmitter on template elements',
829829
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
830-
tcb.overrideView(MyComp, new ViewMetadata({
831-
template: '<template emitter listener></template>',
832-
directives: [DirectiveEmitingEvent, DirectiveListeningEvent]
833-
}))
830+
tcb.overrideView(
831+
MyComp, new ViewMetadata({
832+
template: '<template emitter listener (event)="ctxProp=$event"></template>',
833+
directives: [DirectiveEmitingEvent, DirectiveListeningEvent]
834+
}))
834835

835836
.createAsync(MyComp)
836837
.then((rootTC) => {
837838

838839
var tc = rootTC.debugElement.componentViewChildren[0];
839840
var emitter = tc.inject(DirectiveEmitingEvent);
841+
var myComp = tc.inject(MyComp);
840842
var listener = tc.inject(DirectiveListeningEvent);
841843

844+
myComp.ctxProp = '';
842845
expect(listener.msg).toEqual('');
843846

844847
ObservableWrapper.subscribe(emitter.event, (_) => {
845848
expect(listener.msg).toEqual('fired !');
849+
expect(myComp.ctxProp).toEqual('fired !');
846850
async.done();
847851
});
848852

0 commit comments

Comments
 (0)
X Tutup