Ionic 3 > Master-Detail App using the split-pane component


A little while back, the brilliant guys @ Ionic released a ‘split-pane’ component that promised to move ionic apps a step closer to being truly responsive, all the way up to the desktop. Whilst their post announcing the new component looked great, all the examples seemed to use the new component to display a menu alongside your main app content. Whilst I’m sure this will be a popular approach, I wanted to use the split-panel to help me implement a ‘master-detail’ style app, like this…

Image for post
Image for post

…and there didn’t seem to be any examples out there to help get up and running with this type of thing. So…

Getting started

I created a ‘blank’ ionic 3 project, created using the ionic-cli. To this, I added 3 pages (see github for all demo code):

  • An ‘Items’ page to contain our list items (the ‘master view’)
  • An ‘Item’ page to display an individual item (the ‘detail view’)
  • A ‘Placeholder’ page to ‘fill the gap’ on desktop when no ‘item’ is selected

Now, whilst getting this to work, the key idea to think about is that:

  • On desktop, you’re going to need two ionic NavControllers, one for the master view, and one for the detail view
  • On mobile, you’re only going to need one ionic NavController, and your going to want to hide the detail view

So, thats…

Image for post
Image for post

So how do we do this? Well, we’ll need to:

  • Tweaking the ‘split-pane’ components CSS so that the detail view is hidden on mobile
  • Add a ‘Proxy’ navigation service to simplify working with up to two NavControllers
  • Somehow ‘mark’ your pages as master or detail so that we can tell in code what type of page we are dealing with
  • Add the split-pane component to our app and listen to when its activated/deactivated
  • Wire it all together

1. Tweak ‘split-pane’ component styles (LESS)

.split-pane-side:not(ion-menu) {
display: initial;

2. Add a ‘Proxy’ navigation service

import { Injectable } from '@angular/core';
import { Nav } from 'ionic-angular';
import { PlaceholderPage } from '../pages/placeholder/placeholder';
import { _DetailPage } from '../pages/_DetailPage';

Then add this to the ‘providers’ array of your angular module:

import {
} from '../services/NavProxy.service';

3. ‘Mark’ pages as either ‘master’ or ‘detail’

There are a number of ways you could achieve this…I opted to ‘extend’ Ionic page components with two custom abstract classes:

export abstract class _MasterPage { }
export abstract class _DetailPage { }

The master page, Items was then extended with _MasterPage , and the detail page, with _DetailPage:

export class ItemsPage extends _MasterPage { ... }

These are used by our NavProxyService to detect what type of page it is working with, and internally is used to decide which NavController to push a page to.

4. Add the ‘split-pane’ component to our app & listen for when it’s activated/deactivated

In /src/app/app.html we’re going to add the ion-split-pane component and two ion-nav components to handle our master and detail navigation stack (notice (ionChange=’…’) on the ion-split-pane ):

<ion-nav [root]="masterPage"
<ion-nav [root]="detailPage"
#detailNav main>

5. Wire it all together

This part is pretty simple, just set up our NavProxyService in /src/app/app.component.ts':

import { Component, ViewChild } from '@angular/core';
import { NavProxyService } from '../services/NavProxy.service';
import { ItemsPage } from '../pages/items/items';
import { PlaceholderPage } from '../pages/placeholder/placeholder';

…and, amend /src/pages/items to use our NavProxyService d when requesting detail pages:

import { NavProxyService } from '../../services/NavProxy.service';
import {_MasterPage, ItemPage } from '../';

And that’s pretty much it. Just fire it up with an ionic serve and you should be away…

Image for post
Image for post

Hope that helps.

Demo code:

Written by

Contractor, Front-End and UX Enthusiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store