diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts
index 0250295795..2261a57782 100644
--- a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts
+++ b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts
@@ -596,6 +596,46 @@ describe('i18n support in the template compiler', () => {
verify(input, output);
});
+ it('should support complex expressions in interpolation', () => {
+ const input = `
+
{
{{ valueA | async }}
{{ valueA?.a?.b }}
+ {{ valueA.getRawValue()?.getTitle() }}
`;
const output = String.raw `
var $I18N_0$;
if (ngI18nClosureMode) {
- const $MSG_EXTERNAL_1482713963707913023$$APP_SPEC_TS_0$ = goog.getMsg(" {$interpolation} {$interpolation_1} ", {
+ const $MSG_EXTERNAL_5146016486383316049$$APP_SPEC_TS_1$ = goog.getMsg(" {$interpolation} {$interpolation_1} {$interpolation_2} ", {
"interpolation": "\uFFFD0\uFFFD",
- "interpolation_1": "\uFFFD1\uFFFD"
+ "interpolation_1": "\uFFFD1\uFFFD",
+ "interpolation_2": "\uFFFD2\uFFFD"
});
- $I18N_0$ = $MSG_EXTERNAL_1482713963707913023$$APP_SPEC_TS_0$;
+ $I18N_0$ = $MSG_EXTERNAL_5146016486383316049$$APP_SPEC_TS_1$;
}
else {
$I18N_0$ = $localize \` $` +
String.raw `{"\uFFFD0\uFFFD"}:interpolation: $` +
- String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: \`;
+ String.raw `{"\uFFFD1\uFFFD"}:interpolation_1: $` +
+ String.raw `{"\uFFFD2\uFFFD"}:interpolation_2: \`;
}
…
template: function MyComponent_Template(rf, ctx) {
@@ -1081,8 +1124,10 @@ describe('i18n support in the template compiler', () => {
$r3$.ɵɵelementEnd();
}
if (rf & 2) {
+ var $tmp_2_0$ = null;
+ const $currVal_2$ = ($tmp_2_0$ = ctx.valueA.getRawValue()) == null ? null : $tmp_2_0$.getTitle();
$r3$.ɵɵselect(1);
- $r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 2, ctx.valueA))(ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b);
+ $r3$.ɵɵi18nExp($r3$.ɵɵpipeBind1(2, 3, ctx.valueA))(ctx.valueA == null ? null : ctx.valueA.a == null ? null : ctx.valueA.a.b)($currVal_2$);
$r3$.ɵɵi18nApply(1);
}
}
@@ -2615,9 +2660,9 @@ describe('i18n support in the template compiler', () => {
function MyComponent_div_2_Template(rf, ctx) {
if (rf & 1) {
$r3$.ɵɵelementStart(0, "div", $_c2$);
- i0.ɵɵtext(1, " ");
+ $r3$.ɵɵtext(1, " ");
$r3$.ɵɵi18n(2, $I18N_3$);
- i0.ɵɵtext(3, " ");
+ $r3$.ɵɵtext(3, " ");
$r3$.ɵɵelementEnd();
}
if (rf & 2) {
diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts
index cf00bc8269..af1c151d6a 100644
--- a/packages/compiler/src/render3/view/template.ts
+++ b/packages/compiler/src/render3/view/template.ts
@@ -664,7 +664,7 @@ export class TemplateDefinitionBuilder implements t.Visitor
, LocalResolver
hasBindings = true;
bindings.push({
sourceSpan: element.sourceSpan,
- value: () => this.convertExpressionBinding(expression)
+ value: () => this.convertPropertyBinding(expression)
});
});
}
@@ -1155,19 +1155,12 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver
this._bindingScope.getOrCreateSharedContextVar(0);
}
- private convertExpressionBinding(value: AST): o.Expression {
- const convertedPropertyBinding = convertPropertyBinding(
- this, this.getImplicitReceiverExpr(), value, this.bindingContext(), BindingForm.TrySimple);
- return convertedPropertyBinding.currValExpr;
- }
-
private convertPropertyBinding(value: AST): o.Expression {
const convertedPropertyBinding = convertPropertyBinding(
this, this.getImplicitReceiverExpr(), value, this.bindingContext(), BindingForm.TrySimple,
() => error('Unexpected interpolation'));
const valExpr = convertedPropertyBinding.currValExpr;
this._tempVariables.push(...convertedPropertyBinding.stmts);
-
return valExpr;
}
diff --git a/packages/core/test/acceptance/i18n_spec.ts b/packages/core/test/acceptance/i18n_spec.ts
index 13ff777e95..fccbdf8519 100644
--- a/packages/core/test/acceptance/i18n_spec.ts
+++ b/packages/core/test/acceptance/i18n_spec.ts
@@ -75,14 +75,27 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
});
it('should support interpolations with complex expressions', () => {
- loadTranslations(
- {'{$interpolation} - {$interpolation_1}': '{$interpolation} - {$interpolation_1} (fr)'});
- const fixture =
- initWithTemplate(AppComp, `{{ name | uppercase }} - {{ obj?.a?.b }}
`);
- expect(fixture.nativeElement.innerHTML).toEqual(`ANGULAR - (fr)
`);
- fixture.componentRef.instance.obj = {a: {b: 'value'}};
+ loadTranslations({
+ ' {$interpolation} - {$interpolation_1} - {$interpolation_2} ':
+ ' {$interpolation} - {$interpolation_1} - {$interpolation_2} (fr) '
+ });
+ const fixture = initWithTemplate(AppComp, `
+
+ {{ name | uppercase }} -
+ {{ obj?.a?.b }} -
+ {{ obj?.getA()?.b }}
+
+ `);
+ // the `obj` field is not yet defined, so 2nd and 3rd interpolations return empty strings
+ expect(fixture.nativeElement.innerHTML).toEqual(` ANGULAR - - (fr)
`);
+
+ fixture.componentRef.instance.obj = {
+ a: {b: 'value 1'},
+ getA: () => ({b: 'value 2'}),
+ };
fixture.detectChanges();
- expect(fixture.nativeElement.innerHTML).toEqual(`ANGULAR - value (fr)
`);
+ expect(fixture.nativeElement.innerHTML)
+ .toEqual(` ANGULAR - value 1 - value 2 (fr)
`);
});
it('should support elements', () => {
@@ -1057,6 +1070,25 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
expect(fixture.debugElement.children[0].children[0].references.ref.test).toBe('Set');
expect(fixture.debugElement.children[1].children[0].references.ref.test).toBe('Set');
});
+
+ it('with complex expressions', () => {
+ loadTranslations({
+ '{$interpolation} - {$interpolation_1} - {$interpolation_2}':
+ '{$interpolation} - {$interpolation_1} - {$interpolation_2} (fr)'
+ });
+ const fixture = initWithTemplate(AppComp, `
+
+ `);
+ // the `obj` field is not yet defined, so 2nd and 3rd interpolations return empty strings
+ expect(fixture.nativeElement.firstChild.title).toEqual(`ANGULAR - - (fr)`);
+
+ fixture.componentRef.instance.obj = {
+ a: {b: 'value 1'},
+ getA: () => ({b: 'value 2'}),
+ };
+ fixture.detectChanges();
+ expect(fixture.nativeElement.firstChild.title).toEqual(`ANGULAR - value 1 - value 2 (fr)`);
+ });
});
it('should work with directives and host bindings', () => {