Whats the best way to navigate between views?


#1

I have to admit I’m confused about the best way to navigate between views in my Ionic App. I’m not looking for people to write or debug my code but to guide me as to which method is recommended (if any).

I have an app with three main views and as number of sub-views off the main views. This works well using the tabs navigation as in the ‘standard’ downloaded app. The history stack is maintained and no issues. This is very, very close to the standard ‘tabs’ app that is one of the starter apps. Its pretty much spot on for our use. We’ve changed some of the names but thats about it.

e.g.

Page 1
–> Sub-Page 1.1

Page 2
–> Sub-page 2.1

Page 3

However I am now handling push notifications which can come in at any time in any view and need to ‘programatically’ move to other sub-views using JavaScript from anywhere at all with the right parameter.

I want to maintain the history stack as thats important.

So far I’ve seen and tried out

window.location.href = “#/something/#id

or

$location(…)

or

$state.go(statename , args)

All these partially work in certain circumstances, e.g. if I’m on one of the main pages (page1) I can go to a sub page (page 1.1) and the history is maintained. However if I’m on different page (page 3) and want to go to page1.1 it appears the history is lost, i.e. no back button is presented. I’m going round in circles trying to work it out and the team is getting rather frazzled about it all :smile:

We’ve seen and read masses of posting which all seem to go round in circles and are almost self referential. We cannot see anything in the Ionic docs which is authoritative (though we could have missed it). Its also not clear how ui-router fits into this if at all.

So is there any guide that is easy for the hard-of-understanding to work out the easiest/most recommended/best_practise way to move between views (and sub-views) using JavaScript.

Thanks,

Rob


#2

i have to fight against those problems in some apps and i could not find any real solution

  1. try to avoid navigation cycles!
  2. use $state.go
  3. consider to show notification info in a modal or popup and do not route directly to the view if the app is in foreground. it is a bad behavior if the user changes or reads something in the current view and gets totally interrupted.
  4. communication is everything --> show a hint "hey there are news you can get it blahblahblah).

Alternative --> build own backbutton handling, but that will be hard.


#3

Thanks for the reply.

  1. Not sure what you mean by navigation cycles. I suspect its where you end up one view calling another and back on itself. Agreed.

  2. Ok on $state.go. We’ll try and standardise on that.

  3. Agreed. I wasn’t clear. The user puts the app into the background which could be showing any view. A notification comes in, the user selects it from the notification section, this opens the app and we have to navigate to the information in the notification. Thats acceptable. I agree that we don’t change things over in the foreground which we don’t.

  4. We do show a hint (beep and a flag appear in the title bar) when a notification comes in.

Don’t want to build own state handling, really don’t want to do that :frowning:


#4

i think nobody wants to implement an own state handling ^^

in other cases try to find another handling of notifications like --> you can open notification details in a modal so you do not leave the current state annnd you see the information. but that depends on your requirements.


#5

The issue for us is that it actually makes sense to open the notification directly into another view [edited from window to view]. A model that works is how Google’s inbox has a notification showing a new e-mail, you click on it and it opens up in a view on the phone.

Opending a modal window is doable but involves the user doing more clicks to get to the information.

We’ll have a think about it. Perhaps we can do some internal state changes behind the scenes so that we know the app is in the right state before we come out of background processing.

Rob


#6

The Ionic framework uses the angular-ui-router module for handling routes and defining states (including nested states and nested views).

That means you should always use:

<a ui-sref="app.editor({postId: item.post.id})">Go!</a>

or:

$state.go('app.editor', {postId: item.post.id});

to transition between views.

The ‘Back’ button issue is a separate (but related) issue, for example:


#7

Thanks for the update on which method to use. We have been using $window.location.href="#/…/…/…" but we’ll switch to $state.go and see if that works.

So far our issue appears to be going from one specific page to a sub view on another page when coming out of background mode (pretty specific).

Rob


#8

I think I’ve worked out what the problem is and what a potential solution is, so thanks for the help from here to guide my thoughts.

I think the problem is that I am trying to navigate to a sub-view of one view from a different view.

here is my app.js

.config(function($stateProvider, $urlRouterProvider , $ionicConfigProvider) {
    
        $ionicConfigProvider.tabs.position('bottom'); 
   
        $stateProvider
    
      // setup an abstract state for the tabs directive
        .state('tab', {
        url: "/tab",
        abstract: true,
            templateUrl: "templates/tabs.html"
      })
    
      // Each tab has its own nav history stack:
    
      .state('tab.summary', {
        url: '/summary',
        views: {
          'tab-summary': {
            templateUrl: 'templates/tab-summary.html',
            controller: 'SummaryCtrl'
          }
        }
      })
    
      .state('tab.routes', {
          url: '/routes',
          views: {
            'tab-routes': {
              templateUrl: 'templates/tab-routes.html',
              controller: 'RoutesCtrl'
            }
          }
        })
        .state('tab.route-detail', {
          url: '/routes/:routeId',
          views: {
            'tab-routes': {
              templateUrl: 'templates/route-detail.html',
              controller: 'RouteDetailCtrl'
            }
          }
        })
       .state('tab.detail', {
                  url: '/detail/:detailId',
                      views: {
                      'tab-summary': {
                          templateUrl: 'templates/detail.html',
                              controller: 'DetailCtrl'
                              }
                  }
              })
       .state('tab.jamcam', {
                  url: '/jamcam/:jamcamId',
                      views: {
                      'tab-summary': {
                          templateUrl: 'templates/jamcam.html',
                              controller: 'JamCamCtrl'
                              }
                  }
              })

  .state('tab.settings', {
    url: '/settings',
    views: {
      'tab-settings': {
        templateUrl: 'templates/tab-settings.html',
        controller: 'SettingsCtrl'
      }
    }
  });

  // if none of the above states are matched, use this as the fallback
  $urlRouterProvider.otherwise('/tab/summary');

});

This (hopefully) matches the starter tabs app though I have changed the names around to reflect our app.

My issue was going from the ‘tab.settings’ page to the ‘tab.detail’ page using
$state.go(‘tab.detail’ , {detailId: }).

The issues were that the history button disappeared and a leaflet.js map element on the ‘tab.detail’ page also didn’t work properly. However most of the page was correct and the right information was displayed. I know leaflet.js is a little picky on how its used and will work that issue out separately.

I think these issues are because I am jumping directly into the ‘tab.detail’ page rather than going through ‘tab.summary’ first. However my understanding of sub-views (if that is the right terminology) is poor and no matter how much I read it doesn’t really seem to become any clear, hence I took the starter tabs app and kept it more or less the same.

I think the resolution I have is to make the tab.detail page a wholly separate page and NOT a subview of tab.summary. tab.detail is then only accessible through links on the tab.summary page and its NOT available through the tabs at the bottom of the page. This puts tab.detail at the same level as the tab.summary, tab.routes and tab.settings. This means I lose the navigation back button on the top of the tab.detail page BUT the user can still navigate back using the tabs at the bottom of the page. This feels right to me.

I’ll program it up and see what happens.

Thanks for the replies and help, much appreciated

Rob