Skip to content
Permalink
Browse files

fix(ivy): better support for i18n attributes on <ng-container>s (#33599)

Prior to this commit, i18n runtime logic used `elementAttributeInternal` function (that uses `setAttribute` function under the hood) for all elements where i18n attributes are present. However the `<ng-container>` elements in a template may also have i18n attributes and calling `setAttribute` fails, since they are represented as comment nodes in DOM. This commit ensures that we call `setAttribute` on nodes with TNodeType.Element type (that support that operation) only.

PR Close #33599
  • Loading branch information
AndrewKushnir authored and atscott committed Nov 5, 2019
1 parent 3419b50 commit 204620291e2c8de29cfbed7cf74d401ef376d413
Showing with 33 additions and 2 deletions.
  1. +6 −2 packages/core/src/render3/i18n.ts
  2. +27 −0 packages/core/test/acceptance/i18n_spec.ts
@@ -1011,9 +1011,13 @@ function i18nAttributesFirstPass(lView: LView, tView: TView, index: number, valu
generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes);
}
} else {
elementAttributeInternal(previousElementIndex, attrName, value, lView);
// Check if that attribute is a directive input
const tNode = getTNode(previousElementIndex, lView);
// Set attributes for Elements only, for other types (like ElementContainer),
// only set inputs below
if (tNode.type === TNodeType.Element) {
elementAttributeInternal(previousElementIndex, attrName, value, lView);
}
// Check if that attribute is a directive input
const dataValue = tNode.inputs && tNode.inputs[attrName];
if (dataValue) {
setInputsForProperty(lView, dataValue, value);
@@ -1268,6 +1268,33 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => {
expect(comp.attributes['messagetext']).toBe('Bonjour');
expect(comp.attributes['ng-reflect-message-text']).toBe('Bonjour');
});

it('should support i18n attributes on <ng-container> elements', () => {
loadTranslations({[computeMsgId('Hello', 'meaning')]: 'Bonjour'});

@Directive({selector: '[mydir]'})
class Dir {
@Input() mydir: string = '';
}

@Component({
selector: 'my-cmp',
template: `
<ng-container i18n-mydir="meaning|description" mydir="Hello"></ng-container>
`,
})
class Cmp {
}

TestBed.configureTestingModule({
declarations: [Cmp, Dir],
});
const fixture = TestBed.createComponent(Cmp);
fixture.detectChanges();

const dir = fixture.debugElement.childNodes[0].injector.get(Dir);
expect(dir.mydir).toEqual('Bonjour');
});
});

it('should work with directives and host bindings', () => {

0 comments on commit 2046202

Please sign in to comment.
You can’t perform that action at this time.