根据用户的语言在angular2应用程序中动态加载不同的css文件

Sob*_*han 9 angular2-services angular

我有一个Angular2应用程序,它需要支持多种语言.其中一些语言可能是RTL(即波斯语),有些语言可能是LTR(即英语).除了本地化字符串之外,我还需要根据语言的方向设置组件的样式.

现在使用这个帮助器,我可以有两个单独的文件(即app-rtl.scss和app-ltr.scss),它们都导入一个scss文件(即app.scss),它允许我在一个地方写我的scss代码,自动输出两个文件; 每个方向一个.

问题是现在我需要以某种方式根据用户的语言引用合适的css文件.因此,如果用户的语言是英语,然后我应该 <link href="app-ltr.css" rel="stylesheet">在头,如果它是RTL, <link href="app-rtl.css" rel="stylesheet">.此外,我想为我的项目添加bootstrap,并且还有两个不同的LTR和RTL输出文件.

有没有干净的方法来实现这个功能?

我尝试过的:

我创建了两个虚拟组件(一个用于LTR,一个用于RTL),没有任何模板,然后分配相应的scss文件styleUrls并设置encapsulation: ViewEncapsulation.None为使其成为全局样式.然后我使用*ngIf在我的根组件模板中初始化它们,并检查语言是否为LTR.

这将适用于第一页加载,因为只有一个组件(比如组件LTR)处于活动状态,但只要您更改语言(即第二个组件(RTL)变为活动状态并因此删除了LTR),则与之关联的样式LTR停留在页面上,不会被删除.那么你的页面上既有RTL又有LTR样式,而不是你想要的.

Mil*_*lad 9

您需要有条件地从浏览器中添加或删除样式:

加上

loadIfNot(url,cssId){

     if (!document.getElementById(cssId)){
        var head  = document.getElementsByTagName('head')[0];
        var link  = document.createElement('link');
        link.id   = cssId;
        link.rel  = 'stylesheet';
        link.type = 'text/css';
        link.href = url;
        link.media = 'all';
        head.appendChild(link);
    }else{
        document.getElementById(cssId).disabled = false;///i fit's already there, enable it
    }

  }
Run Code Online (Sandbox Code Playgroud)

并删除

 disable(cssId){
     document.getElementById(cssId).disabled = true
 }
Run Code Online (Sandbox Code Playgroud)

Disable并且Enable是因为浏览器倾向于缓存您的样式,并且为了使它们启用或禁用,您需要更改该属性


ela*_*ash 5

根据 @marbug 的回答,我会尝试使用服务并动态加载和卸载您的“语言”组件。

其工作原理如下

import { Injectable, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { LanguageAComponent } from "./language-a.component";
import { LanguageBComponent } from "./language-b.component";
import { Router } from '@angular/router';

@Injectable()
export class LanguageComponentService {
    componentRef: any;

    constructor(private componentFactoryResolver: ComponentFactoryResolver, private router: Router
    ) { }

    loadLanguageA(viewContainerRef: ViewContainerRef) {
        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(LanguageAComponent);
        this.componentRef = viewContainerRef.createComponent(componentFactory);

    }

   loadLanguageB(viewContainerRef: ViewContainerRef) {
        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(LanguageBComponent);
        this.componentRef = viewContainerRef.createComponent(componentFactory);

    }


    unloadComponent() {
        this.componentRef.destroy();
    }

}
Run Code Online (Sandbox Code Playgroud)


小智 2

<body>也许您可以根据用户语言的方向有条件地添加一个类?例如,<body ng-class="{'dir-ltr': ltr, 'dir-rtl': !ltr}">。当然,您必须分别将所有 sass 样式包装在.dir-ltr.dir-rtl中,以便 DOM 的其余部分将使用正确的样式集。这假设在状态加载时解析了语言方向,并且这也在<body>您的角度应用程序的范围内。