I'm trying to change the Ionic 3 Menu side dynamically once user changes the language.
For RTL languages menu needs to be on the right, by default it's set on left.
I subscribe to TranslateService
from @ngx-translate/core
event when the language changes app.components.ts
:
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
console.info(`Language change to ${event.lang}`);
this.isRTL = event.lang == 'ar' || event.lang == 'fa';
if (event.lang == 'ar' || event.lang == 'fa') {
this.platform.setDir('rtl', true);
this.menuSide = 'right';
} else {
this.platform.setDir('ltr', true);
this.menuSide = 'left';
}
this.platform.setLang(event.lang, true);
});
The code above gets executed successfully when I the language gets changes and all the variables get set as expected (I've written unit tests to be sure and tons of console.logs while the app is running.)
In the template:
<ion-menu [content]="content" [side]="isRTL?'right':'left'" side="{{menuSide}}">
....
</ion-menu>
However, even though the this.menuSide
changes in the controller, it won't work as expected.
It seems the side can be changed only before platform.ready()
, once the platform.ready()
is done, no matter what I set it won’t take any effects.
Edit:
I've tried to use the method in https://stackoverflow.com/a/46417869/636136 but that didn't fix it too.
If I just print menuSide
in the template it would have the correct value on the screen, but doesn't have any effect on the menu direction.
I can change the "side" attribute on the menu element manually via browser element inspector and it will change the direction successfully, however using menuSide
variable won't do the job.
- Source code available at https://github.com/SavandBros/gonevis-mobile/blob/master/src/app/app.html
I was able to change the side of the ion-menu
via HTMLElement
directly.
I know this is not recommended and it should be handled the way I was trying to make it work in the original question, but that's all I could come up with after trying so many different ways.
I believe the problem I have with ion-menu
and its behavior on changing the side is a bug.
Here's what I've changed to get it working.
app.component.ts
export class MyApp {
#...
menuSide: string = "left";
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
console.info(`Language change to ${event.lang}`);
let element: HTMLElement = document.getElementById("lovelyMenu");
if (event.lang == 'ar' || event.lang == 'fa') {
this.platform.setDir('rtl', true);
this.menuSide = 'right';
} else {
this.platform.setDir('ltr', true);
this.menuSide = 'left';
}
element.setAttribute("side", this.menuSide);
this.platform.setLang(event.lang, true);
});
}
...
}
app.html
:
<ion-menu [content]="content" [side]="menuSide" id="lovelyMenu">
....
The commit on Github repo is at github.com/SavandBros/gonevis-mobile/commit/684e4ba4365594b7a7c10216267a16790538d158
Use property binding
instead of interpolation
.
i.e. [side]="menuSide"
<ion-menu [content]="content" [side]="menuSide">
....
</ion-menu>
put SIDE key in json file for each lang like for example:
ar.json
"SIDE" : "right",
and en.json
"SIDE" : "left",
and then in html
<ion-menu [content]="content" side="{{'SIDE' | translate}}"
....
alternate solution, simple, smooth and works like a charm
In app.html
<ion-content class="ttct-app-side-menu-content">
<ion-list>
<button menuClose ion-item *ngFor="let page of menuPages" (click)="openPage(page)">
{{page}}
</button>
</ion-list>
</ion-content>
</ng-template>
<ion-menu *ngIf="language === 'en'" type="overlay" side="right" [content]="content">
<ng-container *ngTemplateOutlet="ttctSideMenuContent"></ng-container>
</ion-menu>
<ion-menu *ngIf="language === 'ar'" type="overlay" side="left" [content]="content">
<ng-container *ngTemplateOutlet="ttctSideMenuContent"></ng-container>
</ion-menu>
In app.component.ts
this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
if(this.translateService.currentLang === 'en') {
platform.setDir('ltr', true);
} else {
platform.setDir('rtl', true);
}
platform.setLang(this.translateService.currentLang, true);
});
.
.
.
.
.
changeLanguage(lang) {
this.translateService.use(lang);
this.language = lang;
}