fix(ivy): ensure unique template and listener function identifiers (#27766)

Previously, there could be identical template/listener function names
for a component's template, if it had multiple similarly structured
nested sub-templates or listeners.
This resulted in build errors:
`Identifier '<SOME_IDENTIFIER>' has already been declared`

This commit fixes this by ensuring that the template index is included
in the `contextName` passed to the `TemplateDefinitionBuilder`
responsible for processing nested sub-templates.
Similarly, the template or element index is included in the listener
names.

PR Close #27766
This commit is contained in:
George Kalpakas
2019-01-04 12:28:11 -08:00
committed by Kara Erickson
parent d026b675be
commit 48555f95c6
8 changed files with 296 additions and 177 deletions
@@ -767,7 +767,7 @@ describe('compiler compliance', () => {
const MyComponentDefinition = `
const $c1$ = ["foo", ""];
const $c2$ = ["if", ""];
function MyComponent_li_Template_2(rf, ctx) {
function MyComponent_li_2_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "li");
$r3$.ɵtext(1);
@@ -789,7 +789,7 @@ describe('compiler compliance', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "ul", null, $c1$);
$r3$.ɵtemplate(2, MyComponent_li_Template_2, 2, 2, "li", $c2$);
$r3$.ɵtemplate(2, MyComponent_li_2_Template, 2, 2, "li", $c2$);
$r3$.ɵelementEnd();
}
},
@@ -1093,10 +1093,10 @@ describe('compiler compliance', () => {
app: {
'spec.ts': `
import {Component, Directive, NgModule, TemplateRef} from '@angular/core';
@Component({selector: 'simple', template: '<div><ng-content></ng-content></div>'})
export class SimpleComponent {}
@Component({
selector: 'complex',
template: \`
@@ -1104,10 +1104,10 @@ describe('compiler compliance', () => {
<div id="second"><ng-content SELECT="span[title=toSecond]"></ng-content></div>\`
})
export class ComplexComponent { }
@NgModule({declarations: [SimpleComponent, ComplexComponent]})
export class MyModule {}
@Component({
selector: 'my-app',
template: '<simple>content</simple> <complex></complex>'
@@ -1176,7 +1176,7 @@ describe('compiler compliance', () => {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
template: \`
<div id="second" *ngIf="visible">
@@ -1191,7 +1191,7 @@ describe('compiler compliance', () => {
\`,
})
class Cmp {}
@NgModule({ declarations: [Cmp] })
class Module {}
`
@@ -1200,20 +1200,20 @@ describe('compiler compliance', () => {
const output = `
const $_c0$ = [${AttributeMarker.SelectOnly}, "ngIf"];
const $_c1$ = ["id", "second"];
function Cmp_div_Template_0(rf, ctx) { if (rf & 1) {
function Cmp_div_0_Template(rf, ctx) { if (rf & 1) {
$r3$.ɵelementStart(0, "div", $_c1$);
$r3$.ɵprojection(1, 1);
$r3$.ɵelementEnd();
} }
const $_c4$ = ["id", "third"];
function Cmp_div_Template_1(rf, ctx) {
function Cmp_div_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "div", $_c4$);
$r3$.ɵtext(1, " No ng-content, no instructions generated. ");
$r3$.ɵelementEnd();
}
}
function Cmp_ng_template_Template_2(rf, ctx) {
function Cmp_ng_template_2_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtext(0, " '*' selector: ");
$r3$.ɵprojection(1);
@@ -1225,9 +1225,9 @@ describe('compiler compliance', () => {
template: function Cmp_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵprojectionDef($_c2$, $_c3$);
$r3$.ɵtemplate(0, Cmp_div_Template_0, 2, 0, "div", $_c0$);
$r3$.ɵtemplate(1, Cmp_div_Template_1, 2, 0, "div", $_c0$);
$r3$.ɵtemplate(2, Cmp_ng_template_Template_2, 2, 0, "ng-template");
$r3$.ɵtemplate(0, Cmp_div_0_Template, 2, 0, "div", $_c0$);
$r3$.ɵtemplate(1, Cmp_div_1_Template, 2, 0, "div", $_c0$);
$r3$.ɵtemplate(2, Cmp_ng_template_2_Template, 2, 0, "ng-template");
}
if (rf & 2) {
$r3$.ɵelementProperty(0, "ngIf", $r3$.ɵbind(ctx.visible));
@@ -1245,7 +1245,7 @@ describe('compiler compliance', () => {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
template: \`
<ng-content select="[id=toMainBefore]"></ng-content>
@@ -1254,7 +1254,7 @@ describe('compiler compliance', () => {
<ng-template>
<ng-content select="[id=toNestedTemplate]"></ng-content>
</ng-template>
</ng-template>
</ng-template>
<ng-template>
'*' selector in a template: <ng-content></ng-content>
</ng-template>
@@ -1262,7 +1262,7 @@ describe('compiler compliance', () => {
\`,
})
class Cmp {}
@NgModule({ declarations: [Cmp] })
class Module {}
`
@@ -1270,18 +1270,18 @@ describe('compiler compliance', () => {
};
const output = `
function Cmp_ng_template_ng_template_Template_1(rf, ctx) {
function Cmp_ng_template_1_ng_template_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵprojection(0, 4);
}
}
}
function Cmp_ng_template_Template_1(rf, ctx) {
function Cmp_ng_template_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵprojection(0, 3);
$r3$.ɵtemplate(1, Cmp_ng_template_ng_template_Template_1, 1, 0, "ng-template");
}
$r3$.ɵtemplate(1, Cmp_ng_template_1_ng_template_1_Template, 1, 0, "ng-template");
}
}
function Cmp_ng_template_Template_2(rf, ctx) {
function Cmp_ng_template_2_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtext(0, " '*' selector in a template: ");
$r3$.ɵprojection(1);
@@ -1294,10 +1294,10 @@ describe('compiler compliance', () => {
if (rf & 1) {
$r3$.ɵprojectionDef($_c2$, $_c3$);
$r3$.ɵprojection(0, 1);
$r3$.ɵtemplate(1, Cmp_ng_template_Template_1, 2, 0, "ng-template");
$r3$.ɵtemplate(2, Cmp_ng_template_Template_2, 2, 0, "ng-template");
$r3$.ɵtemplate(1, Cmp_ng_template_1_Template, 2, 0, "ng-template");
$r3$.ɵtemplate(2, Cmp_ng_template_2_Template, 2, 0, "ng-template");
$r3$.ɵprojection(3, 2);
}
}
}
`;
@@ -1911,7 +1911,7 @@ describe('compiler compliance', () => {
const $c2$ = ["if", ""];
const $c3$ = ["baz", ""];
const $c4$ = ["bar", ""];
function MyComponent_div_span_Template_2(rf, ctx) {
function MyComponent_div_3_span_2_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "span");
$r3$.ɵtext(1);
@@ -1926,11 +1926,11 @@ describe('compiler compliance', () => {
$r3$.ɵtextBinding(1, $r3$.ɵinterpolation3("", $foo$, "-", $bar$, "-", $baz$, ""));
}
}
function MyComponent_div_Template_3(rf, ctx) {
function MyComponent_div_3_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "div");
$r3$.ɵtext(1);
$r3$.ɵtemplate(2, MyComponent_div_span_Template_2, 2, 3, "span", $c2$);
$r3$.ɵtemplate(2, MyComponent_div_3_span_2_Template, 2, 3, "span", $c2$);
$r3$.ɵelement(3, "span", null, $c4$);
$r3$.ɵelementEnd();
}
@@ -1952,7 +1952,7 @@ describe('compiler compliance', () => {
if (rf & 1) {
$r3$.ɵelement(0, "div", null, $c1$);
$r3$.ɵtext(2);
$r3$.ɵtemplate(3, MyComponent_div_Template_3, 5, 2, "div", $c2$);
$r3$.ɵtemplate(3, MyComponent_div_3_Template, 5, 2, "div", $c2$);
$r3$.ɵelement(4, "div", null, $c3$);
}
if (rf & 2) {
@@ -2000,7 +2000,7 @@ describe('compiler compliance', () => {
const $c1$ = ["foo", ""];
const $c2$ = [${AttributeMarker.SelectOnly}, "ngIf"];
function MyComponent_div_span_Template_3(rf, ctx) {
function MyComponent_div_0_span_3_Template(rf, ctx) {
if (rf & 1) {
$i0$.ɵelementStart(0, "span");
$i0$.ɵtext(1);
@@ -2013,11 +2013,11 @@ describe('compiler compliance', () => {
}
}
function MyComponent_div_Template_0(rf, ctx) {
function MyComponent_div_0_Template(rf, ctx) {
if (rf & 1) {
$i0$.ɵelementStart(0, "div");
$i0$.ɵelement(1, "div", null, $c1$);
$i0$.ɵtemplate(3, MyComponent_div_span_Template_3, 2, 2, "span", $c2$);
$i0$.ɵtemplate(3, MyComponent_div_0_span_3_Template, 2, 2, "span", $c2$);
$i0$.ɵelementEnd();
}
if (rf & 2) {
@@ -2029,7 +2029,7 @@ describe('compiler compliance', () => {
// ...
template:function MyComponent_Template(rf, ctx){
if (rf & 1) {
$i0$.ɵtemplate(0, MyComponent_div_Template_0, 4, 1, "div", $c0$);
$i0$.ɵtemplate(0, MyComponent_div_0_Template, 4, 1, "div", $c0$);
}
if (rf & 2) {
$i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items));
@@ -2224,7 +2224,7 @@ describe('compiler compliance', () => {
const MyComponentDefinition = `
const $t1_attrs$ = ["for", "", ${AttributeMarker.SelectOnly}, "forOf"];
function MyComponent__svg_g_Template_1(rf, ctx) {
function MyComponent__svg_g_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵnamespaceSVG();
$r3$.ɵelementStart(0,"g");
@@ -2243,7 +2243,7 @@ describe('compiler compliance', () => {
if (rf & 1) {
$r3$.ɵnamespaceSVG();
$r3$.ɵelementStart(0,"svg");
$r3$.ɵtemplate(1, MyComponent__svg_g_Template_1, 2, 0, ":svg:g", $t1_attrs$);
$r3$.ɵtemplate(1, MyComponent__svg_g_1_Template, 2, 0, ":svg:g", $t1_attrs$);
$r3$.ɵelementEnd();
}
if (rf & 2) { $r3$.ɵelementProperty(1,"forOf",$r3$.ɵbind(ctx.items)); }
@@ -2300,7 +2300,7 @@ describe('compiler compliance', () => {
const MyComponentDefinition = `
const $t1_attrs$ = ["for", "", ${AttributeMarker.SelectOnly}, "forOf"];
function MyComponent_li_Template_1(rf, ctx) {
function MyComponent_li_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "li");
$r3$.ɵtext(1);
@@ -2321,7 +2321,7 @@ describe('compiler compliance', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "ul");
$r3$.ɵtemplate(1, MyComponent_li_Template_1, 2, 1, "li", $t1_attrs$);
$r3$.ɵtemplate(1, MyComponent_li_1_Template, 2, 1, "li", $t1_attrs$);
$r3$.ɵelementEnd();
}
if (rf & 2) {
@@ -2380,7 +2380,7 @@ describe('compiler compliance', () => {
const MyComponentDefinition = `
const $t4_attrs$ = ["for", "", ${AttributeMarker.SelectOnly}, "forOf"];
function MyComponent_li_li_Template_4(rf, ctx) {
function MyComponent_li_1_li_4_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "li");
$r3$.ɵtext(1);
@@ -2393,14 +2393,14 @@ describe('compiler compliance', () => {
}
}
function MyComponent_li_Template_1(rf, ctx) {
function MyComponent_li_1_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "li");
$r3$.ɵelementStart(1, "div");
$r3$.ɵtext(2);
$r3$.ɵelementEnd();
$r3$.ɵelementStart(3, "ul");
$r3$.ɵtemplate(4, MyComponent_li_li_Template_4, 2, 2, "li", $t4_attrs$);
$r3$.ɵtemplate(4, MyComponent_li_1_li_4_Template, 2, 2, "li", $t4_attrs$);
$r3$.ɵelementEnd();
$r3$.ɵelementEnd();
}
@@ -2421,7 +2421,7 @@ describe('compiler compliance', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "ul");
$r3$.ɵtemplate(1, MyComponent_li_Template_1, 5, 2, "li", $c1$);
$r3$.ɵtemplate(1, MyComponent_li_1_Template, 5, 2, "li", $c1$);
$r3$.ɵelementEnd();
}
if (rf & 2) {
@@ -24,13 +24,13 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, NgModule} from '@angular/core';
@Directive({selector: '[i18n]'})
export class I18nDirective {}
@Component({selector: 'my-component', template: '<div i18n></div>'})
export class MyComponent {}
@NgModule({declarations: [I18nDirective, MyComponent]})
export class MyModule{}`
}
@@ -39,11 +39,11 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent,
selectors: [["my-component"]],
factory: function MyComponent_Factory(t) { return new (t || MyComponent)(); },
consts: 1,
vars: 0,
type: MyComponent,
selectors: [["my-component"]],
factory: function MyComponent_Factory(t) { return new (t || MyComponent)(); },
consts: 1,
vars: 0,
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelement(0, "div");
@@ -64,7 +64,7 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, NgModule} from '@angular/core';
@Directive({selector: '[i18n]'})
export class I18nDirective {}
@@ -73,10 +73,10 @@ describe('compiler compliance: directives', () => {
@Directive({selector: '[foo]'})
export class FooDirective {}
@Component({selector: 'my-component', template: '<div i18n-foo></div>'})
export class MyComponent {}
@NgModule({declarations: [I18nDirective, I18nFooDirective, FooDirective, MyComponent]})
export class MyModule{}`
}
@@ -85,11 +85,11 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent,
selectors: [["my-component"]],
factory: function MyComponent_Factory(t) { return new (t || MyComponent)(); },
consts: 1,
vars: 0,
type: MyComponent,
selectors: [["my-component"]],
factory: function MyComponent_Factory(t) { return new (t || MyComponent)(); },
consts: 1,
vars: 0,
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelement(0, "div");
@@ -111,15 +111,15 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, Input, NgModule} from '@angular/core';
@Directive({selector: '[someDirective]'})
export class SomeDirective {
@Input() someDirective;
}
@Component({selector: 'my-component', template: '<div [someDirective]="true"></div>'})
export class MyComponent {}
@NgModule({declarations: [SomeDirective, MyComponent]})
export class MyModule{}
`
@@ -129,7 +129,7 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
…
…
const _c0 = [${AttributeMarker.SelectOnly}, "someDirective"];
…
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
@@ -184,7 +184,7 @@ describe('compiler compliance: directives', () => {
const MyComponentDefinition = `
…
const $_c0$ = ["directiveA", ""];
function MyComponent_ng_template_Template_0(rf, ctx) {
function MyComponent_ng_template_0_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtext(0, "Some content");
}
@@ -194,7 +194,7 @@ describe('compiler compliance: directives', () => {
…
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 0, "ng-template", $_c0$);
$r3$.ɵtemplate(0, MyComponent_ng_template_0_Template, 1, 0, "ng-template", $_c0$);
}
},
…
@@ -238,7 +238,7 @@ describe('compiler compliance: directives', () => {
…
const $_c0$ = [${AttributeMarker.SelectOnly}, "ngIf"];
const $_c1$ = ["directiveA", ""];
function MyComponent_ng_container_Template_0(rf, ctx) {
function MyComponent_ng_container_0_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementContainerStart(0, $_c1$);
$r3$.ɵtext(1, "Some content");
@@ -250,7 +250,7 @@ describe('compiler compliance: directives', () => {
…
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtemplate(0, MyComponent_ng_container_Template_0, 2, 0, "ng-container", $_c0$);
$r3$.ɵtemplate(0, MyComponent_ng_container_0_Template, 2, 0, "ng-container", $_c0$);
}
if (rf & 2) {
$r3$.ɵelementProperty(0, "ngIf", $r3$.ɵbind(ctx.showing));
@@ -272,15 +272,15 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, Input, NgModule} from '@angular/core';
@Directive({selector: '[someDirective]'})
export class SomeDirective {
@Input() someDirective;
}
@Component({selector: 'my-component', template: '<ng-template [someDirective]="true"></ng-template>'})
export class MyComponent {}
@NgModule({declarations: [SomeDirective, MyComponent]})
export class MyModule{}
`
@@ -290,14 +290,14 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
…
…
const $c0_a0$ = [${AttributeMarker.SelectOnly}, "someDirective"];
…
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
…
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 0, 0, "ng-template", $c0_a0$);
$r3$.ɵtemplate(0, MyComponent_ng_template_0_Template, 0, 0, "ng-template", $c0_a0$);
}
if (rf & 2) {
$r3$.ɵelementProperty(0, "someDirective", $r3$.ɵbind(true));
@@ -321,15 +321,15 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, Input, NgModule} from '@angular/core';
@Directive({selector: '[someDirective]'})
export class SomeDirective {
@Input() someDirective;
}
@Component({selector: 'my-component', template: '<div *someDirective></div>'})
export class MyComponent {}
@NgModule({declarations: [SomeDirective, MyComponent]})
export class MyModule{}
`
@@ -338,14 +338,14 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
…
…
const $c0_a0$ = ["someDirective", ""];
…
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
…
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtemplate(0, MyComponent_div_Template_0, 1, 0, "div", $c0_a0$);
$r3$.ɵtemplate(0, MyComponent_div_0_Template, 1, 0, "div", $c0_a0$);
}
},
…
@@ -367,17 +367,17 @@ describe('compiler compliance: directives', () => {
app: {
'spec.ts': `
import {Component, Directive, Output, EventEmitter, NgModule} from '@angular/core';
@Directive({selector: '[someDirective]'})
export class SomeDirective {
@Output() someDirective = new EventEmitter();
}
@Component({selector: 'my-component', template: '<div (someDirective)="noop()"></div>'})
export class MyComponent {
noop() {}
}
@NgModule({declarations: [SomeDirective, MyComponent]})
export class MyModule{}
`
@@ -387,7 +387,7 @@ describe('compiler compliance: directives', () => {
// MyComponent definition should be:
const MyComponentDefinition = `
…
…
const $c0_a0$ = [${AttributeMarker.SelectOnly}, "someDirective"];
…
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
@@ -395,7 +395,7 @@ describe('compiler compliance: directives', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "div", $c0_a0$);
$r3$.ɵlistener("someDirective", function MyComponent_Template_div_someDirective_listener($event) { return ctx.noop(); });
$r3$.ɵlistener("someDirective", function MyComponent_Template_div_someDirective_0_listener($event) { return ctx.noop(); });
$r3$.ɵelementEnd();
}
},
File diff suppressed because it is too large Load Diff
@@ -46,7 +46,7 @@ describe('compiler compliance: listen()', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "div", $e0_attrs$);
$r3$.ɵlistener("click", function MyComponent_Template_div_click_listener($event) {
$r3$.ɵlistener("click", function MyComponent_Template_div_click_0_listener($event) {
ctx.onClick($event);
return (1 == 2);
});
@@ -92,7 +92,7 @@ describe('compiler compliance: listen()', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "my-app", $e0_attrs$);
$r3$.ɵlistener("click", function MyComponent_Template_my_app_click_listener($event) {
$r3$.ɵlistener("click", function MyComponent_Template_my_app_click_0_listener($event) {
return ctx.onClick($event);
});
$r3$.ɵelementEnd();
@@ -136,19 +136,19 @@ describe('compiler compliance: listen()', () => {
const $t0_attrs$ = [${AttributeMarker.SelectOnly}, "ngIf"];
const $e_attrs$ = [${AttributeMarker.SelectOnly}, "click"];
function MyComponent_div_Template_0(rf, ctx) {
function MyComponent_div_0_Template(rf, ctx) {
if (rf & 1) {
const $s$ = $r3$.ɵgetCurrentView();
$r3$.ɵelementStart(0, "div");
$r3$.ɵelementStart(1, "div", $e_attrs$);
$r3$.ɵlistener("click", function MyComponent_div_Template_0_div_click_listener($event) {
$r3$.ɵlistener("click", function MyComponent_div_0_Template_div_click_1_listener($event) {
$r3$.ɵrestoreView($s$);
const $comp$ = $r3$.ɵnextContext();
return $comp$.onClick($comp$.foo);
});
$r3$.ɵelementEnd();
$r3$.ɵelementStart(2, "button", $e_attrs$);
$r3$.ɵlistener("click", function MyComponent_div_Template_0_button_click_listener($event) {
$r3$.ɵlistener("click", function MyComponent_div_0_Template_button_click_2_listener($event) {
$r3$.ɵrestoreView($s$);
const $comp2$ = $r3$.ɵnextContext();
return $comp2$.onClick2($comp2$.bar);
@@ -160,7 +160,7 @@ describe('compiler compliance: listen()', () => {
// ...
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵtemplate(0, MyComponent_div_Template_0, 3, 0, "div", $c0$);
$r3$.ɵtemplate(0, MyComponent_div_0_Template, 3, 0, "div", $c0$);
}
if (rf & 2) {
$i0$.ɵelementProperty(0, "ngIf", $i0$.ɵbind(ctx.showing));
@@ -208,7 +208,7 @@ describe('compiler compliance: listen()', () => {
if (rf & 1) {
const $s$ = $r3$.ɵgetCurrentView();
$r3$.ɵelementStart(0, "button", $e0_attrs$);
$r3$.ɵlistener("click", function MyComponent_Template_button_click_listener($event) {
$r3$.ɵlistener("click", function MyComponent_Template_button_click_0_listener($event) {
$r3$.ɵrestoreView($s$);
const $user$ = $r3$.ɵreference(3);
return ctx.onClick($user$.value);
@@ -281,8 +281,8 @@ describe('compiler compliance: styling', () => {
template: function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵelementStart(0, "div", _c0);
$r3$.ɵlistener("@myAnimation.start", function MyComponent_Template_div__myAnimation_start_listener($event) { return ctx.onStart($event); });
$r3$.ɵlistener("@myAnimation.done", function MyComponent_Template_div__myAnimation_done_listener($event) { return ctx.onDone($event); });
$r3$.ɵlistener("@myAnimation.start", function MyComponent_Template_div__myAnimation_start_0_listener($event) { return ctx.onStart($event); });
$r3$.ɵlistener("@myAnimation.done", function MyComponent_Template_div__myAnimation_done_0_listener($event) { return ctx.onDone($event); });
$r3$.ɵelementEnd();
} if (rf & 2) {
$r3$.ɵelementProperty(0, "@myAnimation", $r3$.ɵbind(ctx.exp));
File diff suppressed because it is too large Load Diff
@@ -632,7 +632,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
element.outputs.forEach((outputAst: t.BoundEvent) => {
this.creationInstruction(
outputAst.sourceSpan, R3.listener,
this.prepareListenerParameter(element.name, outputAst));
this.prepareListenerParameter(element.name, outputAst, elementIndex));
});
}
@@ -707,9 +707,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}
const tagName = sanitizeIdentifier(template.tagName || '');
const contextName = tagName ? `${this.contextName}_${tagName}` : '';
const templateName =
contextName ? `${contextName}_Template_${templateIndex}` : `Template_${templateIndex}`;
const contextName = `${tagName ? this.contextName + '_' + tagName : ''}_${templateIndex}`;
const templateName = `${contextName}_Template`;
const parameters: o.Expression[] = [
o.literal(templateIndex),
@@ -780,7 +779,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
template.outputs.forEach((outputAst: t.BoundEvent) => {
this.creationInstruction(
outputAst.sourceSpan, R3.listener,
this.prepareListenerParameter('ng_template', outputAst));
this.prepareListenerParameter('ng_template', outputAst, templateIndex));
});
}
@@ -1062,14 +1061,16 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
return this.constantPool.getConstLiteral(asLiteral(refsParam), true);
}
private prepareListenerParameter(tagName: string, outputAst: t.BoundEvent): () => o.Expression[] {
private prepareListenerParameter(tagName: string, outputAst: t.BoundEvent, index: number):
() => o.Expression[] {
let eventName: string = outputAst.name;
if (outputAst.type === ParsedEventType.Animation) {
eventName = prepareSyntheticAttributeName(`${outputAst.name}.${outputAst.phase}`);
}
const evNameSanitized = sanitizeIdentifier(eventName);
const tagNameSanitized = sanitizeIdentifier(tagName);
const functionName = `${this.templateName}_${tagNameSanitized}_${evNameSanitized}_listener`;
const functionName =
`${this.templateName}_${tagNameSanitized}_${evNameSanitized}_${index}_listener`;
return () => {
@@ -222,22 +222,22 @@
"name": "TemplateRef"
},
{
"name": "ToDoAppComponent_footer_Template_6"
"name": "ToDoAppComponent_footer_6_Template"
},
{
"name": "ToDoAppComponent_footer_button_Template_5"
"name": "ToDoAppComponent_footer_6_button_5_Template"
},
{
"name": "ToDoAppComponent_section_Template_5"
"name": "ToDoAppComponent_section_5_Template"
},
{
"name": "ToDoAppComponent_section_input_Template_1"
"name": "ToDoAppComponent_section_5_input_1_Template"
},
{
"name": "ToDoAppComponent_section_li_Template_3"
"name": "ToDoAppComponent_section_5_li_3_Template"
},
{
"name": "ToDoAppComponent_section_li_input_Template_6"
"name": "ToDoAppComponent_section_5_li_3_input_6_Template"
},
{
"name": "Todo"