Skip to content

Commit

Permalink
fix(TranslateDirective): update dom content on lang change
Browse files Browse the repository at this point in the history
  • Loading branch information
ocombe committed Dec 5, 2016
1 parent fb1ac1d commit a209ad2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
27 changes: 20 additions & 7 deletions src/translate.directive.ts
Expand Up @@ -24,7 +24,7 @@ export class TranslateDirective implements AfterViewChecked, OnDestroy {
// subscribe to onLangChange event, in case the language changes
if(!this.onLangChangeSub) {
this.onLangChangeSub = this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
this.checkNodes(true);
this.checkNodes(event.translations);
});
}
}
Expand All @@ -33,7 +33,7 @@ export class TranslateDirective implements AfterViewChecked, OnDestroy {
this.checkNodes();
}

checkNodes(langChanged = false) {
checkNodes(translations?: any) {
let nodes: NodeList = this.element.nativeElement.childNodes;
for(let i = 0; i < nodes.length; ++i) {
let node: any = nodes[i];
Expand All @@ -49,26 +49,28 @@ export class TranslateDirective implements AfterViewChecked, OnDestroy {
key = content;
// the content was changed from the user, we'll use it as a reference if needed
node.originalContent = node.textContent;
} else if(node.originalContent && langChanged) { // the content seems ok, but the lang has changed
} else if(node.originalContent && isDefined(translations)) { // the content seems ok, but the lang has changed
node.lastKey = null;
// the current content is the translation, not the key, use the last real content as key
key = node.originalContent.trim();
}
}
}
this.updateValue(key, node);
this.updateValue(key, node, translations);
}
}
}

updateValue(key: string, node: any) {
updateValue(key: string, node: any, translations: any) {
if(key) {
let interpolateParams: Object = this.translateParams;
if(node.lastKey === key && this.lastParams === interpolateParams) {
return;
}

this.lastParams = interpolateParams;
this.translateService.get(key, interpolateParams).subscribe((res: string | any) => {

let onTranslation = (res: string) => {
if(res !== key) {
node.lastKey = key;
}
Expand All @@ -78,7 +80,18 @@ export class TranslateDirective implements AfterViewChecked, OnDestroy {
node.currentValue = isDefined(res) ? res : (node.originalContent || key);
// we replace in the original content to preserve spaces that we might have trimmed
node.textContent = this.key ? node.currentValue : node.originalContent.replace(key, node.currentValue);
});
};

if(isDefined(translations)) {
let res = this.translateService.getParsedResult(translations, key, interpolateParams);
if(typeof res.subscribe === "function") {
res.subscribe(onTranslation);
} else {
onTranslation(res);
}
} else {
this.translateService.get(key, interpolateParams).subscribe(onTranslation);
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions tests/translate.directive.spec.ts
Expand Up @@ -101,4 +101,18 @@ describe('TranslateDirective', () => {

expect(fixture.componentInstance.withParamsNoKey.nativeElement.innerHTML).toEqual('It is ok');
});

it('should update the DOM when the lang changes', () => {
expect(fixture.componentInstance.noKey.nativeElement.innerHTML).toEqual('TEST');

translate.setTranslation('en', {"TEST": "This is a test"});
translate.setTranslation('fr', {"TEST": "C'est un test"});

translate.use('en');
expect(fixture.componentInstance.noKey.nativeElement.innerHTML).toEqual('This is a test');

translate.use('fr');
expect(fixture.componentInstance.noKey.nativeElement.innerHTML).toEqual("C'est un test");
});

});

6 comments on commit a209ad2

@deepu105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ocombe Before this directive I had a simple directive which did the below and with that I was able to to do <p translate="my.foo.key"></p> is there anyway to retain the behavior so that I dont have to rewrite my entire sourcecode to do <p [translate]="'my.foo.key'"></p>?

This is what I used to have

import { Component, Input } from '@angular/core';

@Component({
    selector: '[translate]',
    template: '<span [innerHTML]="translate | translate:translateValues"></span>'
})
export class JhiTranslate {

    @Input('translate') private translate: string;

    @Input('translate-values') translateValues: any;

    //FIXME add support to pass translate-compile/ directives in translated content doesnt work
}

@ocombe
Copy link
Collaborator Author

@ocombe ocombe commented on a209ad2 Dec 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good news, <p translate="my.foo.key"></p> should already work with the directive :)

@deepu105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm for some reason it doesnt work for me. let me dig deeper

@deepu105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok with v4.2.0 this seems to work but somehow the directive doesnt update the content when I switch languages dynamically. The pipe works in the same setup

@ocombe
Copy link
Collaborator Author

@ocombe ocombe commented on a209ad2 Dec 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm this shouldn't be the case, can you open a bug with a plunkr please?

@deepu105
Copy link
Contributor

@deepu105 deepu105 commented on a209ad2 Dec 6, 2016 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.