加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular 5:请求不同布局的多种语言

发布时间:2020-12-17 18:11:20 所属栏目:安全 来源:网络整理
导读:我有一个Angular 5应用程序,默认语言为French.我必须添加需要更改全局布局的阿拉伯语(必须从右到左显示内容……). 我想知道是否有一种方法只使用一个组件并进行条件模板选择.例如 : --my-compenent_ar.html--my-compenent_fr.html--my-component.tsAnd in m
我有一个Angular 5应用程序,默认语言为French.我必须添加需要更改全局布局的阿拉伯语(必须从右到左显示内容……).

我想知道是否有一种方法只使用一个组件并进行条件模板选择.例如 :

--my-compenent_ar.html
--my-compenent_fr.html
--my-component.ts

And in my @Component({
    moduleId: module.id,templateUrl: ==> condition here
    styleUrls: ['./sign-in.component.scss']
})
export class MyComponent

当前版本的Angular(5)本身不支持这种情况.

有什么好办法吗?

我想要做的是

--my-compenent_ar.html
--my-compenent_fr.html
--my-component.ts
--my-component.ar.ts

@Component({
    moduleId: module.id,templateUrl: './my-compenent_fr.html'
    styleUrls: ['./sign-in.component.scss']
})
export class MyComponent {
....
}

@Component({
    moduleId: module.id,templateUrl: './my-compenent_ar.html'
    styleUrls: ['./sign-in.component.scss']
})
export class MyComponentAR extends MyComponent {}

使用此配置,FR语言环境将导航到MyComponent和AR语言环境到MyComponentAR.

这很冗长.你有干净的方法吗?

解决方法

对于那些具有相同场景的人,在我的解决方案下面只使用一个组件并支持更改布局方向.

1.为每种语言创建路线

我们假设我的路线是:

const routes: Routes = [
    {
        path: '',component: HomeComponent,pathMatch: 'full'
    },{
        path: 'users',children: [
            {
                path: '',component: UsersComponent
            },{
                path: ':uid/profile',component: ProfileViewComponent
            }
        ]
    }
]

我们的想法是用支持的语言为这些路由添加前缀.我动态地执行此操作,如下所示(我在这里只使用阿拉伯语言前缀):

/**
 * Initialize language and routes
 * @param routes
 * @returns {Promise<any>}
 */
init(routes: Routes): Promise<any> {

    this.routes = routes;
    let children: Routes = [...this.routes];

    /** exclude certain routes */
    for (let i = children.length - 1; i >= 0; i--) {
        if (children[i].data && children[i].data['skipRouteLocalization']) {
            children.splice(i,1);
        }
    }

    /** append children routes */
    if (children && children.length) {
        if (this.locales.length > 1) {
            this.routes.unshift({path: 'ar',children: children});
        }
    }

    return of(this.routes).toPromise();
}

在app初始化时调用此方法:

@Injectable()
export class ParserInitializer {
    parser: LocalizeParser;
    routes: Routes;

    /**
     * CTOR
     * @param injector
     */
    constructor(private injector: Injector) {
    }

    /**
     * @returns {Promise<any>}
     */
    appInitializer(): Promise<any> {
        const res = this.parser.init(this.routes);

        res.then(() => {
            let router = this.injector.get(Router);
            router.resetConfig(this.parser.routes);
        });

        return res;
    }

    /**
     * @param parser
     * @param routes
     * @returns {()=>Promise<any>}
     */
    generateInitializer(parser: LocalizeParser,routes: Routes[]): () => Promise<any> {
        this.parser = parser;
        this.routes = routes.reduce((a,b) => a.concat(b));
        return this.appInitializer;
    }
}

/**
 * @param p
 * @param parser
 * @param routes
 * @returns {any}
 */
export function getAppInitializer(p: ParserInitializer,parser: LocalizeParser,routes: Routes[]): any {
    return p.generateInitializer(parser,routes).bind(p);
}

@NgModule({
    imports: [CommonModule,RouterModule,TranslateModule],declarations: [],exports: []
})
export class LocalizeRouterModule {

    static forRoot(routes: Routes,config: LocalizeRouterConfig = {}): ModuleWithProviders {
        return {
            ngModule: LocalizeRouterModule,providers: [
                {
                    provide: RAW_ROUTES,multi: true,useValue: routes
                },config.parser,// LocalizeParser,ParserInitializer,{
                    provide: APP_INITIALIZER,useFactory: getAppInitializer,deps: [ParserInitializer,LocalizeParser,RAW_ROUTES]
                }
            ]
        };
    }


}

2.使用Bootstrap RTL

由于阿拉伯语需要布局方向从右到左,我使用RTL Boostrap support来执行此操作.我在.rtl css类中限定了这个rtl css,并在选择arabic时使用angular指令将此css类设置在顶层.

@Directive({
    selector: '[yfLayoutClass]'
})
export class LayoutClassDirective implements OnInit {

    constructor(private elRef: ElementRef,private renderer: Renderer2,private store: Store<fromRoot.State>) {
    }

    ngOnInit(): void {

        this.store.select(fromRoot.getLocale)
            .filter(loc => loc != null)
            .subscribe(locale => {

                if (locale.isArabic()) {
                    this.renderer.addClass(this.elRef.nativeElement,'rtl');
                } else {
                    this.renderer.removeClass(this.elRef.nativeElement,'rtl');
                }

            });


    }

}

3.当lang更改时,重定向到正确的前缀路由

语言更改时,必须将用户重定向到正确的前缀路由.要动态执行此操作,我在appComponent中使用以下代码

public ngOnInit(): void {

    this.translateService.onLangChange
        .combineLatest(this.router.events)
        .subscribe(([langEvent,event]) => {

            if (event instanceof RoutesRecognized) {
                let currentUrl = event.url;

                let locale = Locale.getLocaleByShortcut(langEvent.lang);

                let queryParams = event.state.root.queryParams;

                if (locale) {
                    if (locale.isArabic()) {
                        if (!ContextUtils.isArabicUrl(currentUrl)) {
                            this.router.navigateByUrl(ContextUtils.arabizeUrl(currentUrl),{queryParams: queryParams});
                        }
                    } else {
                        if (ContextUtils.isArabicUrl(currentUrl)) {
                            this.router.navigateByUrl(ContextUtils.frenchifyUrl(currentUrl),{queryParams: queryParams});
                        }
                    }
                }

            }


        });
}

就这样 !像这样你只使用一个组件.

希望能帮助到你 !

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读