Remove navigation bar in sidemenu based template in Ionic/Angular JS - javascript

I created an application using the Ionic Framework and it works great. It is based on the sidemenu-template, so I always have a navigation bar on top of the application.
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-calm">
<ion-nav-back-button></ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon-round" menu-toggle="left"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-content>
<a menu-close href="#/app/bla">
<div id="profile-item">
<i class="icon ion-card"></i> Bla
</div>
</a>
<a menu-close href="#/app/register">
<div id="profile-item">
<i class="icon ion-card"></i> Sign-up
</div>
</a>
<a menu-close href="#/app/login">
<div id="profile-item">
<i class="icon ion-card"></i> Login
</div>
</a>
</ion-content>
</ion-side-menu>
</ion-side-menus>
app.js:
$stateProvider.state('app.login', {
url: '/login',
views: {
'menuContent': {
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
}
}
})
$stateProvider.state('app.start', {
url: '/start',
views: {
'menuContent': {
templateUrl: 'templates/start.html',
controller: 'StartsCtrl'
}
}
})
Now for the registration and login view I don't want to show the navigation bar at all. How can I remove it on specific view? I find this hard because the nav-bar is defined in menu.html which is called before the views.

I had to modify the routes definition in app.js:
$stateProvider.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
$stateProvider.state('start', {
url: '/start',
templateUrl: 'templates/start.html',
controller: 'StartsCtrl'
})
Only removing the toogle button did not work, as the user was still able to swipe right on the screen to show the menu.

Simply hiding the menu-toggle button should do the trick for you.
Set a variable on the rootScope based on which you can show/hide the navigation bar toggle button:
<button ng-if="$root.isShowNav" class="button button-icon button-clear ion-navicon-round" menu-toggle="left">
Set this variable's value inside your app's .run:
.run(function($ionicPlatform, $rootScope) {
// $rootScope.isShowNav = true/false based on some condition.
}
For example, here you could do something like this:
.run(function($ionicPlatform, $rootScope) {
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState) {
if (toState.name !== "app.login" || toState.name !== "app.start") {
$rootScope.isShowNav = true;
}
else {
$rootScope.isShowNav = false;
}
}
}

Related

$state.go leads me to the otherwise statement and does not transition to the right state

I am trying to move into the menu.home state but when I do $state.go('menu.home) it does not do anything and it goes into the otherwise statement. Not sure what I am doing wrong.
Controller.js
$state.go('menu.home');
routes.js
angular.module('app.routes', [])
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
.state('login', {
cache: false,
url:'/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('menu.home', {
cache: false,
url: '/home',
views: {
'side-menu21': {
templateUrl: 'templates/home.html',
controller: 'MapCtrl' //'homeCtrl'
}
}
})
.state('menu.cart', {
url: '/page2',
views: {
'side-menu21': {
templateUrl: 'templates/cart.html',
controller: 'cartCtrl'
}
}
})
.state('menu.cloud', {
url: '/page3',
views: {
'side-menu21': {
templateUrl: 'templates/cloud.html',
controller: 'cloudCtrl'
}
}
})
.state('menu.test', {
cache: false,
url: '/test',
views: {
'side-menu21': {
templateUrl: 'templates/test.html',
controller: 'testCtrl'
}
}
})
.state('menu', {
url: '/side-menu21',
templateUrl: 'templates/menu.html',
abstract: true
})
//$urlRouterProvider.otherwise('/login')
$urlRouterProvider.otherwise(function($injector, $location) {
console.log("Could not find: " + JSON.stringify($location));
$location.path('/login');
})
});
every time I try to do $state.go('menu.home') this is the output i get:
Could not find: {"$$protocol":"http","$$host":"localhost","$$port":8100,"$$path":"/app/sear ch","$$search": {},"$$hash":"","$$url":"/app/search","$$absUrl":"http://localhost:8100/#/ap p/search","$$state":null,"$$replace":false}
login.html
<ion-view view-title="Login" id="login" name="login-view">
<ion-content class="padding">
<!--##########################Facebook Login#################################-->
<div class="facebookLogin">
<a class="facebook-sign-in button button-royal" ng-click="facebookSignIn()">Login with Facebook</a>
</div>
<!--#######################END Facebook Login#################################-->
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="Username" ng-model="data.username">
</label>
<
label class="item item-input">
<input type="password" placeholder="Password" ng-model="data.password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
home.html
<ion-view title="Test" id="home" class=" ">
<ion-content padding="true" class="has-header"></ion-content>
<body ng-app="app" ng-controller="MapCtrl">
<!-- Google Maps -->
<link href="css/style.css" rel="stylesheet">
<ion-content scroll="false">
<div id="map-canvas"></div>
<!-- END GOOGLE MAPS!-->
<!-- Test button
<div class="TestButton">
<div class="button button-assertive" ng-click="Test()" ng-hide="hideTestButton">
<a class="button">Test</a>
</div>
</div>
End Request Test button----------->
<!-- OS/Production selection footer-->
<ion-tabs class="tabs-icon-top">
<ion-tab title="Apple" icon-off="ion-social-apple" icon-on="ion-social-apple" href="#/app/search" on-select="appleTab()">
<ion-nav-view name="tab-search"></ion-nav-view>
</ion-tab>
<ion-tab title="Windows" icon-off="ion-social-windows" icon-on="ion-social-windows" href="#/app/browse" on-select="windowsTab()">
<ion-nav-view name="tab-browse"></ion-nav-view>
</ion-tab>
<ion-tab title="Mobile" icon-off="ion-iphone" icon-on="ion-iphone" href="#/app/playlists" on-select="mobileTab()">
<ion-nav-view name="tab-playlists"></ion-nav-view>
</ion-tab>
<ion-tab title="Network" icon-off="ion-wifi" icon-on="ion-wifi"" href="#/app/playlists" on-select="otherTab()">
<ion-nav-view name="tab-playlists"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-content>
</body>
</ion-view>
If I comment out : $location.path('/login'); then it works. Not sure why this happens, Please help!
Is that all that is in your controller.js file? Maybe there is something in there that is preventing hitting that state. Make sure in your main html file you have <main ui-view></main> to establish all your routes.
Got it, so it does not like the href that i have in my ion-tabs in the home.html. It might be trying to resolve them which are not point to valid urls. Once I removed the href it worked perfectly fine. Thanks for all the help everyone!

Ionic app side menu with a login page

I am building an app that it's navigation based on a side menu. The problem I am having is trying to implement it along with a login page, that is not part of the side menu's scope, so that only after the login, the side menu navigation shall be used.
here's my app.js:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('signin', {
url: '/sign-in',
templateUrl: 'templates/sign-in.html',
controller: 'SignInCtrl'
})
.state('sideMenu', {
url: '/sideMenu',
abstract: true,
templateUrl: 'templates/sideMenu.html',
controller: 'sideMenuCtrl'
})
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'homeTabCtrl'
})
//})
$urlRouterProvider.otherwise('/home');
})
This is the Side menu's HTML:
<ion-view ng-controller="sideMenuCtrl">
<ion-pane ion-side-menu-content>
<ion-nav-bar type="bar-assertive" back-button-type="button-icon" back-button-icon="ion-arrow-left-c"></ion-nav-bar>
<ion-nav-view>
</ion-nav-view>
</ion-pane>
<!-- Left Side Menu -->
<ion-side-menu side="right">
<ion-header-bar class="bar bar-header bar-assertive">
<h1 class="title">Menu</h1>
</ion-header-bar>
<ion-content has-header="true">
<ion-list>
<ion-item ng-click="goTo(item.link)" class="item item-icon-left" ng-repeat="item in list" menu-close>
<!-- <i ng-class="item.iconClass"></i> -->
{{item.text}}
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
The controller:
.controller('sideMenuCtrl', function ($scope, $location, MenuService) {
console.log('Side menu is reloaded');
// "MenuService" is a service returning mock data (services.js)
$scope.list = MenuService.all();
$scope.goTo = function(page) {
console.log('Going to ' + page);
$scope.sideMenuController.toggleLeft();
$location.url('/' + page);
};
})
I have made a small demo for you,
Plunker Demo
html
<ion-view hide-nav-bar="true " class="view-bg-blue">
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" ng-click="openMenu()"></button>
</ion-nav-buttons>
<ion-content padding="true">
<h3 class="text-center">Welcome To Landing Page</h3>
<div class="row">
<div class="col">
<div class="text-center">
<h4>My App</h4>
<div class="row">
<div class="col">
<input placeholder="User">
</div>
</div>
<div class="row">
<div class="col">
<input placeholder="password">
</div>
</div>
<a class="button icon-right ion-chevron-right button-calm" ng-click="open()">Login</a>
</div>
</div>
</div>
</ion-content>
</ion-view>
app.js
var app = angular.module('myApp', ['ionic']);
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tabs', {
url: '/tab',
controller: 'TabsCtrl',
templateUrl: 'tabs.html'
})
.state('tabs.home', {
url: '/home',
views: {
'home-tab': {
controller: 'homeCtrl',
templateUrl: 'home.html'
}
}
})
.state('tabs.settings', {
url: '/settings',
views: {
'settings-tab': {
controller: ' signOutCtrl',
templateUrl: 'settings.html'
}
}
});
$stateProvider
.state('landing', {
url: '/landing',
controller: 'landingCtrl',
templateUrl: 'landing.html'
});
$urlRouterProvider.otherwise('/landing');
});
If you need any additional feature,Please let me know?Thanks

Ionic left sidemenu does not toggle open

Hi I'm relatively new to ionic and I'm trying to get an app running with both a side-menu and a tab bar. Currently the tab bar is working fine just the left side menu does not open when I click the icon. For most of the app I've just been working off of the tutorials on the ionic website.
I am adding google maps to the tabs and I am aiming to have facebook login for the sidebar but the main issue is the tab isn't toggling.
app.js
$stateProvider
.state('menu', {
url: "/menu",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('menu.playlists', {
url: "/playlists",
views: {
'menu' :{
templateUrl: "templates/playlists.html",
controller: 'PlaylistsCtrl'
}
}
})
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.map', {
url: '/map',
views: {
'tab-map': {
templateUrl: 'templates/tab-map.html',
controller: 'MapCtrl'
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/map');
tab-map.html
<ion-view view-title="Safety First">
<ion-nav-buttons side="left" ng-controller="AppCtrl">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-content ng-controller="MapCtrl">
<div id="map" data-tap-disabled="true"></div>
</ion-content>
</ion-view>
menu.html
<ion-side-menus>
<ion-side-menu-content>
<ion-nav-bar class="bar-stable nav-title-slide-ios7">
<ion-nav-back-button class="button-clear"><i class="icon ion-ios7-arrow-back"></i> Back</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="menu" animation="slide-left-right"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<header class="bar bar-header bar-stable">
<h1 class="title">Left</h1>
</header>
<ion-content class="has-header">
<ion-list>
<ion-item nav-clear menu-close href="#/app/about">
About
</ion-item>
<ion-item nav-clear menu-close ng-click="login()">
Login
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
Here is an image of the app's main page
When I click the submenu icon it does not toggle the submenu. The odd part is that If I navigate the app to http://localhost:8100/#/menu/playlists the toggling is fine.
Any suggestions on why nothing is really firing on the click? Perhaps its an issue of which controller is acting at the time?
You have to call the correct function. I'm assuming login() is located inside AppCtrl controller. Because of that, ng-click can't find the function, unless you tell it where it's located. Since AppCtrl is responsible for menu.html, you have to call it like this:
ng-click="this.login()"

Routing issue on ionic

I just started using ionic a few days ago, and I came into an issue.
I am trying to do a side menu where the content would be linked to data present into a controller, and I managed to do it. But what I can't find a solution to, is when you click into that element in the side menu, it shows the full data about the element using the id to find it.
I don't really know how to explain it, so it might be more clear with some code :
app.js :
config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
//leaderboard special menu
.state('leader', {
url: '/leader',
abstract: true,
templateUrl: 'templates/leaderMenu.html',
controller: 'UserCtrl'
})
.state('leader.single', {
url: '/users/:leaderId',
views: {
'menuContent': {
templateUrl: 'templates/user.html',
controller: 'UserCtrl'
}
}
})
.state('leader.user', {
url: '/user',
templateUrl: 'templates/leader_user.html'
})
controller.js :
.controller('UserCtrl', function ($scope) {
$scope.leaderboard = [
{ image: 'jean_kevin.jpg', name: 'Jean-caca', id: 1, star_number: 50 },
{ image: 'jean_kevin.jpg', name: 'Jean-kevin', id: 2, star_number: 42 },
{ image: 'jean_kevin.jpg', name: 'Jean-kevin', id: 3, star_number: 20 }
];})
leaderMenu.html :
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-energized">
<ion-nav-back-button>
</ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-assertive">
<h1 class="title">LeaderBoard</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item ng-repeat="user in leaderboard" menu-close href="#/leader/users/{{user.id}}">
<div class="item item-avatar">
<img src="/img/{{user.image}}" />
<h2>{{user.name}}</h2>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
and user.html :
<link href="../css/my_account.css" rel="stylesheet">
<ion-view view-title="User">
<ion-content>
<div class="photoList">
<ion-list>
<ion-item ng-repeat="user in leaderboard">
<div class="item item-thumbnail-left" style="border:0px">
<img src="../img/{{user.image}}" />
<h2>{{user.name}}</h2>
{{user.star_number}} <i class="icon ion-star"></i>
</div>
</ion-item>
</ion-list>
</div>
</ion-content>
</ion-view>
I know it's not the right way to do in user.html, but I have no idea how to get the id that was selected in that page.
Thanks for your help
You can acces route parameters in controller by using $stateParams service. For your case you can access leaderId like this $stateParams.leaderId. Dont forget to include $stateParams in your controller. One more thing, by seeing your code, i will suggest you to use different controllers. You are using same UserCtrl for sidemenu and other page.
See this Documentation to $stateParams.

$ionicHistory.backView has incorrect state when go to previous state manually

I did a small experiment: http://codepen.io/hawkphil/pen/NqMomm?editors=101
Here is my state flow (click on the buttons): Home -> Fact1 -> Fact2 -> Fact3 -> Fact2
On each state change, I am showing in console.log for $ionicHistory.backView
However, you can see in pen.js:64 line, weird things happen. The $ionicHistory.backView "thinks" that I got to app.fact2 from a back button, and it shows app.fact1 as the previous state (line pen.js:53). This is incorrect, right? It should show app.fact3 as the previous state because I got to app.fact2 state MANUALLY by clicking the button. I also showed the value from $timeout (line pen.js:59) just in case it's slow. But it's still incorrect.
pen.js:56 stateChangeSuccess
pen.js:64 State change from: tabs.home to: tabs.fact1
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal:
pen.js:53 tabs.home
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName
pen.js:59 tabs.home
pen.js:56 stateChangeSuccess
pen.js:64 State change from: tabs.fact1 to: tabs.fact2
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal:
pen.js:53 tabs.fact1
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName
pen.js:59 tabs.fact1
pen.js:56 stateChangeSuccess
pen.js:64 State change from: tabs.fact2 to: tabs.fact3
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal:
pen.js:53 tabs.fact2
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName
pen.js:59 tabs.fact2
pen.js:56 stateChangeSuccess
pen.js:64 State change from: tabs.fact3 to: tabs.fact2
pen.js:52 $scope.$watch $ionicHistory.backView change detect. newVal:
pen.js:53 tabs.fact1
pen.js:58 $timeout after 2 sec $ionicHistory.backView().stateName
pen.js:59 tabs.fact1
QUESTION
How to correct this behavior? Maybe rewrite this delegate or override it somehow?
Is there a workaround? As I rely on the correct previous state in order to show/hide something.
JS
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html",
controller: "MainCtrl"
})
.state('tabs.home', {
url: "/home",
views: {
'home-tab': {
templateUrl: "templates/home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.fact1', {
url: "/fact1",
views: {
'home-tab': {
templateUrl: "templates/fact1.html",
controller: 'Fact1TabCtrl'
}
}
})
.state('tabs.fact2', {
url: "/fact2",
views: {
'home-tab': {
templateUrl: "templates/fact2.html",
controller: 'Fact2TabCtrl'
}
}
})
.state('tabs.fact3', {
url: "/fact3",
views: {
'home-tab': {
templateUrl: "templates/fact3.html",
controller: 'Fact3TabCtrl'
}
}
})
.state('tabs.about', {
url: "/about",
views: {
'about-tab': {
templateUrl: "templates/about.html"
}
}
})
.state('tabs.navstack', {
url: "/navstack",
views: {
'about-tab': {
templateUrl: "templates/nav-stack.html"
}
}
});
$urlRouterProvider.otherwise("/tab/home");
})
.controller('MainCtrl', function($scope, $rootScope, $timeout, $ionicHistory) {
$scope.$watch(function() {
return $ionicHistory.backView() ? $ionicHistory.backView().stateName : null;
}, function (newVal, oldVal) {
console.log('$scope.$watch $ionicHistory.backView change detect. newVal:');
console.log(newVal);
});
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
console.log('stateChangeSuccess');
$timeout(function(){
console.log('$timeout after 2 sec $ionicHistory.backView().stateName');
console.log($ionicHistory.backView().stateName);
}, 2000);
});
})
.controller('HomeTabCtrl', function($scope, $rootScope) {
// console.log('Home');
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
console.log('State change from: ' + fromState.name + ' to: ' + toState.name);
});
})
.controller('Fact1TabCtrl', function($scope) {
// console.log('Fact1');
})
.controller('Fact2TabCtrl', function($scope) {
// console.log('Fact2');
})
.controller('Fact3TabCtrl', function($scope) {
// console.log('Fact3');
});
HTML
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Navigation Example</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button class="button-icon ion-arrow-left-c">
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
<script id="templates/tabs.html" type="text/ng-template">
<ion-tabs class="tabs-icon-top tabs-positive">
<ion-tab title="Home" icon="ion-home" href="#/tab/home">
<ion-nav-view name="home-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="About" icon="ion-ios-football" href="#/tab/about">
<ion-nav-view name="about-tab"></ion-nav-view>
</ion-tab>
</ion-tab>
</ion-tabs>
</script>
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content class="padding">
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact1">
Fact1
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact2">
Fact2
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact3">
Fact3
</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/fact1.html" type="text/ng-template">
<ion-view view-title="Fact1">
<ion-content class="padding">
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact1">
Fact1
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact2">
Fact2
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact3">
Fact3
</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/fact2.html" type="text/ng-template">
<ion-view view-title="Fact2">
<ion-content class="padding">
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact1">
Fact1
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact2">
Fact2
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact3">
Fact3
</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/fact3.html" type="text/ng-template">
<ion-view view-title="Fact3">
<ion-content class="padding">
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact1">
Fact1
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact2">
Fact2
</a>
<a class="button icon icon-right ion-chevron-right" href="#/tab/fact3">
Fact3
</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/about.html" type="text/ng-template">
<ion-view view-title="About">
<ion-content class="padding">
<h3>Create hybrid mobile apps with the web technologies you love.</h3>
<p>Free and open source, Ionic offers a library of mobile-optimized HTML, CSS and JS components for building highly interactive apps.</p>
<p>Built with Sass and optimized for AngularJS.</p>
<p>
<a class="button icon icon-right ion-chevron-right" href="#/tab/navstack">Tabs Nav Stack</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/nav-stack.html" type="text/ng-template">
<ion-view view-title="Tab Nav Stack">
<ion-content class="padding">
<p><img src="http://ionicframework.com/img/diagrams/tabs-nav-stack.png" style="width:100%"></p>
</ion-content>
</ion-view>
</script>
</body>
</html>
There are a lot of questions about history and navigation among the issues open on github.
I guess the navigation is broken and needs to be fixed.
$ionicHistory keeps track of the view pushing each visited view on a stack.
Actually there are 2 arrays there:
$ionicHistory.viewHistory().views
and
$ionicHistory.viewHistory().histories
I guess the first one is the history of views for the current stack while the second considers all the histories.
Different navigations can have different histories: tabs, sidemenu etc etc, and Ionic should remember each state when you switch from one history to the other.
Reading through their documentation you can find this:
Unlike a traditional browser environment, apps and webapps have
parallel independent histories, such as with tabs. Should a user
navigate few pages deep on one tab, and then switch to a new tab and
back, the back button relates not to the previous tab, but to the
previous pages visited within that tab.
You can find the currentHistoryId here: $ionicHistory.currentHistoryId().
I've changed your example a little bit displaying the 2 arrays when entering the view of the main controller:
.controller('MainCtrl', function($scope, $rootScope, $timeout, $ionicHistory) {
$scope.$on('$ionicView.enter', function(e) {
var history = $ionicHistory.viewHistory();
angular.forEach(history.views, function(view, index){
console.log('views: ' + view.stateName);
});
angular.forEach(history.histories[$ionicHistory.currentHistoryId()].stack, function(view, index){
console.log('history stack:' + view.stateName);
});
});
})
As you can see, the first array views keeps track of all the views you have visited.
If you go back and forth in doesn't add elements if you are displaying a view you've previously visited.
Each view has two properties: backViewId and forwardViewId. These 2 values seems to be part of the view when the elements are added to the collection. They don't change when you navigate.
So, what happens is when you follow the sequence:
Home -> Fact1 -> Fact2 -> Fact3 -> Fact2
Ionic finds the view Fact2 in the collection, gets it's backViewId (which points to Fact1) and that's what it will use as a view to go back to.
I didn't some debugging in the code and tried to force the back-view myself but things get messed up.
I guess they've chosen this path cause when you're back to the root - home - the back button should be hidden.
Things don't work as expected when you follow the sequence:
Another thing I've noticed is the fact that sometimes views are added to this collection even if the element is already there.
You can try the sequence:
Home -> Fact1 -> Fact2 - Home (button)
As you can see now the back button (in the header) tells you the back view is Fact2 and in fact the console shows the same:
views: tabs.home
views: tabs.fact1
views: tabs.fact2
views: tabs.home
history stack:tabs.home
history stack:tabs.fact1
history stack:tabs.fact2
history stack:tabs.home
For some strange reason this time a new view has been added to the collection and the regular pattern has changed.
There's a codepen here with some tests.
My solution/workaround:
Create an additional state to traverse to that references the same url, templateUrl, and controller.
For example if I have:
$stateProvider.state('fact2', {
url: '/fact2/:factFilter',
templateUrl: 'fact2.html',
controller: 'Fact2Ctrl'
})
Then I also create a "fact2" duplicate with only a different state name
$stateProvider.state('fact2_duplicate', {
url: '/fact2/:factFilter',
templateUrl: 'fact2.html',
controller: 'Fact2Ctrl'
})
If I am receiving the funny transition behavior, I can call $state.go('fact2_duplicate') and the history will be more inline to what I am expecting.
Hope this helps someone.

Categories

Resources