Для тех, кто имеет тот же сценарий, ниже моего решения, которое использует только один компонент и поддерживает изменение направления макета.
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,
multi: true,
useFactory: getAppInitializer,
deps: [ParserInitializer, LocalizeParser, RAW_ROUTES]
}
]
};
}
}
2.Используйте Bootstrap RTL
Поскольку арабский язык требует направления макета справа налево, для этого я использую Поддержка RTL Boostrap .Я поместил этот rtl css в класс .rtl
css и использовал угловую директиву, чтобы установить этот класс 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});
}
}
}
}
});
}
Вот и все!Таким образом, вы используете только один компонент.
Надеюсь, это поможет!