我有一个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(); }
@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}); } } } } }); }
就这样 !像这样你只使用一个组件.
希望能帮助到你 !