大田区から発信するゆるゆる日記

主にITエンジニアに関する備忘録日記。たまに趣味も。何か不備があればコメント頂けると幸いです。Twitterアカウント https://twitter.com/ryuzan03

【Ionic/Angular】Tabsテンプレートで作ったIonicアプリにSideBarを追加する(別解編)

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

【目次】

概要

この記事は以前書いた記事【Ionic/Angular】Tabsテンプレートで作ったIonicアプリにSideBarを追加する - 大田区から発信するゆるゆる日記の別解となります。

以前書いた記事だと後々面倒なことになりそうだったので、色々と考えてたら下記の別解に辿り着きました。なかなか開発が前に進まないTT

Tabsテンプレートで作ったIonicアプリにSideBarを追加する(別解編)

前回と今回の比較

前回はtabs.pageをcomponent化し、各ページにそのcomponentを設置することで、SideBarメインのページに仕上げました。つまりionic startでsidebarを選んでアプリを作成し、そこにtabs.componentをねじ込んだイメージです。

今回はtabs.pageの中にSidebar.pageを作ります。Sidebar.pageの中で各ページを遷移させるイメージです。

別解に至った経緯

前回ではion-tab-buttonの性質上、属性tabを指定しているとページ遷移時にtabの属性値を現時点のページのURLに『追加』することになり、ルーティングがとてもややこしくなりました。ion-tab-buttonにはhref属性もあるのですが、ion-tabsのページ遷移の恩恵を受けることができない(ページを再読み込みしてしまう)ので却下としました。

ネットで諸先輩方のアプリを漁っているとtabs.pageの中にsidebar.pageを入れていたので、真似てみたら幸せになれました。

Ionicアプリを作成する。

$ ionic start project tabs --type=angular

MenuPageを追加する。
このMenuPageがサイドバーになります。

project $ ionic g page menu

app-routing.module.ts(menuを削除)

...
const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
  }
];
...

tabs-routing.module.ts

...
const routes: Routes = [
  {
    path: 'tabs',
    component: TabsPage,
    children: [
      {
        path: '',
        loadChildren: () => import('../menu/menu.module').then(m => m.MenuPageModule)
      },
      {
        path: '',
        redirectTo: '/tabs/tab1',
        pathMatch: 'full'
      }
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/tab1',
    pathMatch: 'full'
  }
...

manu-routing.module.ts

...
const routes: Routes = [
  {
    path: '',
    component: MenuPage,
    children: [
      {
        path: 'tab1',
          loadChildren: () =>
          import('../tab1/tab1.module').then(m => m.Tab1PageModule),
      },
      {
        path: 'tab2',
          loadChildren: () =>
          import('../tab2/tab2.module').then(m => m.Tab2PageModule),
      },
      {
        path: 'tab3',
          loadChildren: () =>
          import('../tab3/tab3.module').then(m => m.Tab3PageModule)
      },
      {
        path: '',
        redirectTo: '/tabs/tab1',
        pathMatch: 'full'
      }
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/tab1',
    pathMatch: 'full'
  }
];
...

menu.page.html

<ion-split-pane contentId="content">
  <ion-menu contentId="content">

    <ion-header>
      <ion-toolbar color="primary">
        <ion-title>MENU</ion-title>
      </ion-toolbar>
    </ion-header>

    <ion-content>
      <ion-list>
        <ion-menu-toggle auto-hide="false" *ngFor="let p of pages">
          <ion-item [routerLink]="p.url" routerDirection="root" [class.active-item]="selectedPath.startsWith(p.url)">
            <ion-label>
              {{p.title}}
            </ion-label>
          </ion-item>
        </ion-menu-toggle>
      </ion-list>
    </ion-content>
  </ion-menu>

  <ion-router-outlet id="content"></ion-router-outlet>
</ion-split-pane>

menu.page.ts

...
export class MenuPage {

  pages = [
    {
      title: 'tab1',
      url: '/tabs/tab1'
    },
    {
      title: 'tab2',
      url: '/tabs/tab2'
    },
    {
      title: 'tab3',
      url: '/tabs/tab3'
    },
  ];

  selectedPath = '';

  constructor(private router: Router) {
    this.router.events.subscribe((event: RouterEvent) => {
      if (event && event.url) {
        this.selectedPath = event.url;
      }
    });
   }
}


タブの表示/非表示を実装する

TabsPageの表示/非表示を実装します。

tabs.component.scss

@media screen and (min-width: 992px) {
  ion-tab-bar {
    display: none;
  }
}


今後に向けて

ion-tab-buttonの属性について理解していなかったため、ややこしい実装をしてしまいました。
参考書とか見ずに新しい機能を実装する時は、公式リファレンスを見ておいた方が良さそうですね。個人開発だとなかなか難しそうですが。。。

参考資料

素晴らしい記事に感謝致します。
ion-tab-button - Ionic Documentation