Changing Ionic Menu side dynamically

霸气de小男生 提交于 2020-01-03 17:34:56

问题


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

回答1:


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">
....



回答2:


Use property binding instead of interpolation.

i.e. [side]="menuSide"

<ion-menu [content]="content" [side]="menuSide">
....
</ion-menu>



回答3:


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}}"

....




回答4:


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;
  }


来源:https://stackoverflow.com/questions/46417847/changing-ionic-menu-side-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!