Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2: How to modify content of the element with custom directive?

Angular2:

I'm trying to modify the content / innerHTML of the tag which has the custom directive applied.

Preface:

I'm trying to work out a translation functionality for my project which pulls data from DB, loads it into local object and update all translated object values. First I tried with a pipe, but unless the pipe is impure (which comes with performance degradation) - I have no way of updating the value when new translations arrive (Something like this question). Next in line is the directive, although it has larger footprint in the code.

What I tried:

I have a directive like that:

@Directive({
    selector: '[i18n]'
})
export class I18nDirective
{
    @Input() set i18n(key: string) {
        this.el.nativeElement.innerHTML = Translations.get(key);
        this.viewContainer.element.nativeElement.innerHTML = Translations.get(key);
        this.templateRef.elementRef.nativeElement.innerHTML = Translations.get(key);
        this.renderer.setElementProperty(this.el.nativeElement, 'innerHTML', Translations.get(key));
        this.renderer.setElementProperty(this.viewContainer.element.nativeElement, 'innerHTML', Translations.get(key));
        this.renderer.setElementProperty(this.templateRef.elementRef.nativeElement, 'innerHTML', Translations.get(key));

        this.viewContainer.createEmbeddedView(this.templateRef);
    }

    public constructor(
        private el: ElementRef,
        private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef,
        private renderer: Renderer,
    ) { }
}

I've tried all the above variants of settings the contents of the tag under the directive, but without any success.

Here is the tag:

<span class="..." *i18n="'translation-page-title'"></span>

How can I change dynamically the innerHTML of the tag containing the directive? And probably change it dynamically when the language is changed?

Thanks in advance!

like image 610
vuryss Avatar asked Mar 11 '23 12:03

vuryss


1 Answers

When using the * before a directive it automatically wraps the content between the opening and the closing tags with <template>...</template>. Those tags are escaped from the browsers and this gives you the ability to modify the the content. Then you inject it using TemplateRef into the directive and do the modifications using createEmbeddedView. Since you don't need that you can just remove the * and use Renderer to modify the content. Here is a working example without Translations.

like image 82
user1 Avatar answered Mar 13 '23 13:03

user1