diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/GOLDEN_PARTIAL.js
index c65ce590881c0..330673b8425cd 100644
--- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/GOLDEN_PARTIAL.js
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/GOLDEN_PARTIAL.js
@@ -1249,13 +1249,13 @@ import * as i0 from "@angular/core";
export class MyComponent {
}
MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
-MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: '{{this.a}}', isInline: true });
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, isStandalone: true, selector: "my-component", ngImport: i0, template: '{{a}}', isInline: true });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{
type: Component,
args: [{
selector: 'my-component',
standalone: true,
- template: '{{this.a}}',
+ template: '{{a}}',
}]
}] });
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.js
index 8779f7708cd72..9591f67d00b03 100644
--- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.js
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.js
@@ -2,7 +2,7 @@ MyComponent_ng_template_0_Template(rf, ctx) {
if (rf & 1) {
i0.ɵɵtext(0);
} if (rf & 2) {
- const $a_r1$ = i0.ɵɵnextContext();
+ const $a_r1$ = ctx.$implicit;
i0.ɵɵtextInterpolate($a_r1$);
}
}
@@ -15,4 +15,4 @@ function MyComponent_Template(rf, ctx) {
} if (rf & 2) {
i0.ɵɵproperty("ngIf", true);
}
-}
\ No newline at end of file
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.ts
index d4033861a55c1..62a9a9a1563d6 100644
--- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.ts
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_template/ng_template_implicit.ts
@@ -3,7 +3,7 @@ import {Component} from '@angular/core';
@Component({
selector: 'my-component',
standalone: true,
- template: '{{this.a}}',
+ template: '{{a}}',
})
export class MyComponent {
p1!: any;
diff --git a/packages/compiler/src/render3/view/t2_binder.ts b/packages/compiler/src/render3/view/t2_binder.ts
index be87bac5a782c..8d19507022f86 100644
--- a/packages/compiler/src/render3/view/t2_binder.ts
+++ b/packages/compiler/src/render3/view/t2_binder.ts
@@ -922,21 +922,13 @@ class TemplateBinder extends RecursiveAstVisitor implements Visitor {
private maybeMap(ast: PropertyRead | SafePropertyRead | PropertyWrite, name: string): void {
// If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
// `AST` expression that maps to a `Variable` or `Reference`.
- if (!(ast.receiver instanceof ImplicitReceiver)) {
+ if (!(ast.receiver instanceof ImplicitReceiver) || ast.receiver instanceof ThisReceiver) {
return;
}
// Check whether the name exists in the current scope. If so, map it. Otherwise, the name is
// probably a property on the top-level component context.
const target = this.scope.lookup(name);
-
- // It's not allowed to read template entities via `this`, however it previously worked by
- // accident (see #55115). Since `@let` declarations are new, we can fix it from the beginning,
- // whereas pre-existing template entities will be fixed in #55115.
- if (target instanceof LetDeclaration && ast.receiver instanceof ThisReceiver) {
- return;
- }
-
if (target !== null) {
this.bindings.set(ast, target);
}
diff --git a/packages/compiler/test/render3/view/binding_spec.ts b/packages/compiler/test/render3/view/binding_spec.ts
index 9d97a459e99b6..2d054b9dd0a7f 100644
--- a/packages/compiler/test/render3/view/binding_spec.ts
+++ b/packages/compiler/test/render3/view/binding_spec.ts
@@ -373,6 +373,35 @@ describe('t2 binding', () => {
expect((target as a.LetDeclaration)?.name).toBe('value');
});
+ it('should not resolve a `this` access to a template reference', () => {
+ const template = parseTemplate(
+ `
+
+ {{this.value}}
+ `,
+ '',
+ );
+ const binder = new R3TargetBinder(new SelectorMatcher());
+ const res = binder.bind({template: template.nodes});
+ const interpolationWrapper = (template.nodes[1] as a.BoundText).value as e.ASTWithSource;
+ const propertyRead = (interpolationWrapper.ast as e.Interpolation).expressions[0];
+ const target = res.getExpressionTarget(propertyRead);
+
+ expect(target).toBe(null);
+ });
+
+ it('should not resolve a `this` access to a template variable', () => {
+ const template = parseTemplate(`{{this.value}}`, '');
+ const binder = new R3TargetBinder(new SelectorMatcher());
+ const res = binder.bind({template: template.nodes});
+ const templateNode = template.nodes[0] as a.Template;
+ const interpolationWrapper = (templateNode.children[0] as a.BoundText).value as e.ASTWithSource;
+ const propertyRead = (interpolationWrapper.ast as e.Interpolation).expressions[0];
+ const target = res.getExpressionTarget(propertyRead);
+
+ expect(target).toBe(null);
+ });
+
it('should not resolve a `this` access to a `@let` declaration', () => {
const template = parseTemplate(
`
diff --git a/packages/core/test/acceptance/embedded_views_spec.ts b/packages/core/test/acceptance/embedded_views_spec.ts
index a7ce9bd7731aa..839ec7811a0b2 100644
--- a/packages/core/test/acceptance/embedded_views_spec.ts
+++ b/packages/core/test/acceptance/embedded_views_spec.ts
@@ -44,7 +44,7 @@ describe('embedded views', () => {
});
it('should resolve template input variables through the implicit receiver', () => {
- @Component({template: `{{this.a}}`})
+ @Component({template: `{{a}}`})
class TestCmp {}
TestBed.configureTestingModule({declarations: [TestCmp]});