Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ionic history work and when is a non-root stack created?

I'm using ionic v1.0.0 and do not understand the way parallel history managed by $ionicHistory works.

Especially on Android devices, when using the (formerly hardware-)back button, my Angular app sometimes behaves strange and I'd like to understand why. (example: navigating back opens a view closed by $ionicGoBack() long time ago)

For me it seems like some of the ui-router navigations create new history stacks and others put the history items in the root history, even when going from state to sub-state should append to the history where state is recorded IMO.

Questions

  • Can anybody explain in which cases ui-sref or $state.go(...) append history items to a newly created stack?
  • When are they appended to root?
  • Are modals treated in a special way?

Sorry for not being more specific, but the app is rather complicated and I don't know how to isolate the problems in a single plunkr. Maybe I missed a piece of good documentation...

like image 724
hgoebl Avatar asked Jul 02 '15 13:07

hgoebl


People also ask

What is NavController in Ionic?

NavController is the base class for navigation controller components like Nav and Tab . You use navigation controllers to navigate to pages in your app. At a basic level, a navigation controller is an array of pages representing a particular history (of a Tab for example).

How do I redirect to another page in Ionic?

to​ A redirect route, redirects "from" a URL "to" another URL. This property is that "to" URL. When the defined ion-route-redirect rule matches, the router will redirect to the path specified in this property.

How to navigate Ionic?

Navigation in Ionic works like a simple stack, where we push new pages onto the top of the stack, which takes us forwards in the app and shows a back button. To go backwards, we pop the top page off.

What is the use of app component in Ionic project?

Ionic apps are made of high-level building blocks called components. Components allow you to quickly construct an interface for your app. Ionic comes with a number of components, including modals, popups, and cards.


2 Answers

I'll try to answer this question even if you might not find all the info you're asking.

Lot of people - included myself - seem to struggle to understand how the navigation system and the history works.

I've answered a question earlier trying to explain why things don't work as expected. It seems the navigation keeps track of each view the user has visited using a collection. Actually there are 2 collections in the $ionicHistory object. The first one $ionicHistory.viewHistory().views seems to keep track of each visited view in the current stack while the other $ionicHistory.viewHistory().histories keeps track of all the histories for the whole app.

You might have different types of history for tabs, sidemenus or regular views.

You can see how parallel independent histories work in this codepen.
There are 2 different histories there. One is for the home tab and the second is for the about tab.

Navigating through the sub-items in each tab and going back to the previous tab you'll notice that the navigation system has remember the previous state.

I've prepared another plunker here where you can see how the navigation works with some details displayed in the page.

The collection of views $ionicHistory.viewHistory().views is updated each time the user visits a new page (the current view in the collection is wrapped in square brackets).

If the view has been added to the collection it won't (it shouldn't) be added again.

You can change the behaviour clearing the history ($ionicHistory.clearHistory()) or setting the root for the current history:

$ionicHistory.nextViewOptions({     historyRoot: true }); 

In the Invoice page of my plunker there's a green button (Other Root View). When pressed I set the new history root and change state:

$ionicHistory.nextViewOptions({     historyRoot: true }); $state.go('otherviewroot'); 

Things work as expected and in fact now I don't have a back view and my stack contains only the current view.

Things get messed up when you try the sequence:

Home - Contacts - Invoices - Home (button in the header). 

Now it's seems Ionic has lost control of the sequence and keeps on adding views to the collection.

Pressing the home button should clear the back button, since we are on the root for the current history, but it doesn't happen.

Using the same pattern over and over increases the size of the collection indefinitely.

I guess this is not the right behaviour and a fix is needed.

Going back to your question.

The back button in Android works ... meaning the it follows the same pattern.

Modals luckily are not treated as regular views and don't affect the collection.

like image 179
LeftyX Avatar answered Sep 21 '22 15:09

LeftyX


As additional information to the previous post.

A history stack is always linked to an "ion-nav-view" template. So the root history stack is created for the first "ion-nav-view" item.

If you plan on using different history stacks I would advise to always link the ion-nav-view to a view name: <ion-nav-view name="default"></ion-nav-view> instead of <ion-nav-view></ion-nav-view>

In this CodePen you have a RootStack for the tab pages and the other pages (named "tabs", "other", "other1") and then inside the tab pages you have one substack for each tab. The tab pages and other pages run inside the Root ion-nav-view. During my tests I needed to assign a name to the root ion-nav-view and then reference this view name in controller. Otherwise the stack was always recreated when switching between the main pages (Other => Tabs => Other => ..)

Html for Root Stack:

<ion-nav-view name="default"></ion-nav-view> 

Controller:

 .state('other', {       url: "/other",       views: {         'default': {           templateUrl:       "templates/other.html",         }         }, .state('tabs', {       url: "/tab",       abstract: true,      views: {         'default': {           templateUrl:       "templates/tabs.html",         }      }     }) 

Inside the tabs template I assigned a new ion-nav-view for the different tab stacks (as it is done in the default ionic tabs template)

For example for the home-tab (and home stack) the Html looks like this (pages home, facts):

<ion-nav-view name="home-tab"></ion-nav-view> 

Controller:

.state('tabs.home', {       url: "/home",       views: {         'home-tab': {           templateUrl: "templates/home.html",         },        }     })     .state('tabs.facts', {       url: "/facts",       views: {         'home-tab': {           templateUrl: "templates/facts.html",         },                 }     }) 

I also submitted a bug report for the codepen above. It is wrongly switching back across histories. https://github.com/driftyco/ionic/issues/4086

I'm not sure of my fix though. Maybe the history feature needs to be redesigned more globally to address issues ..

like image 32
Fabian Avatar answered Sep 19 '22 15:09

Fabian