fix(compiler): explicitly support event bindings also on <template> elements

Although these events don’t fire events themselves, there might be directives on them that fire events.

Closes #4712
This commit is contained in:
Tobias Bosch
2015-10-13 17:43:15 -07:00
parent b89c5bc581
commit cec8b58373
3 changed files with 58 additions and 9 deletions

View File

@ -220,7 +220,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
parsedElement =
new NgContentAst(this.ngContentCount++, elementNgContentIndex, element.sourceInfo);
} else if (isTemplateElement) {
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps, events,
this._assertAllEventsPublishedByDirectives(directives, events, element.sourceInfo);
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps,
element.sourceInfo);
parsedElement = new EmbeddedTemplateAst(attrs, vars, directives, children,
elementNgContentIndex, element.sourceInfo);
@ -239,7 +240,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, templateElementOrDirectiveProps, templateDirectives);
this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectives, templateElementProps,
[], element.sourceInfo);
element.sourceInfo);
parsedElement = new EmbeddedTemplateAst([], templateVars, templateDirectives, [parsedElement],
component.findNgContentIndex(templateCssSelector),
element.sourceInfo);
@ -567,7 +568,6 @@ class TemplateParseVisitor implements HtmlAstVisitor {
private _assertNoComponentsNorElementBindingsOnTemplate(directives: DirectiveAst[],
elementProps: BoundElementPropertyAst[],
events: BoundEventAst[],
sourceInfo: string) {
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
if (componentTypeNames.length > 0) {
@ -578,9 +578,20 @@ class TemplateParseVisitor implements HtmlAstVisitor {
this._reportError(
`Property binding ${prop.name} not used by any directive on an embedded template in ${prop.sourceInfo}`);
});
}
private _assertAllEventsPublishedByDirectives(directives: DirectiveAst[], events: BoundEventAst[],
sourceInfo: string) {
var allDirectiveEvents = new Set<string>();
directives.forEach(directive => {
StringMapWrapper.forEach(directive.directive.outputs,
(eventName, _) => { allDirectiveEvents.add(eventName); });
});
events.forEach(event => {
this._reportError(
`Event binding ${event.name} on an embedded template in ${event.sourceInfo}`);
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
this._reportError(
`Event binding ${event.fullName} not emitted by any directive on an embedded template in ${sourceInfo}`);
}
});
}
}