Tab navigation / routing issues - tabs displaying incorrect content


#1

I have a tab menu which shows 4 items (code here and codepen just has 2 items for clarity) and a “more” item which leads to further menu choices displayed as a list in an ion-content. I have two possibly connected issues.

Issue 1: at first the app appears to be working correctly but as you start to navigate around a few links (generally after visiting “more”, the tabs will start to return incorrect URLS. For example:

Stating at News > Contact > More > Sports > Contacts > News > More - breaks here, I see Contacts content instead of More content.

I’ve add a console.log into each controller and in Chrome dev tools console, I can see that each tab click seems to lunch an extra event, e.g. clicking news tab means ‘news’ appears twice in the console. In addition, in the nav example above, the console shows that the contacts controller was launched when I clicked More.

Issue 2: Up until the point where the nav breaks as described above, the back button works correctly for pages launched from the tabs, but for the pages launched from the “more” page (ie from the list) there is no back button.

Sorry for all these beginner questions!

Codepen : http://codepen.io/anon/pen/hBpfa

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

   
    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <script src="js/app.js"></script>
    </head>
  <body ng-app="schoolApp"  animation="slide-left-right-ios7">

    <ion-nav-bar class="bar-stable nav-title-slide-ios7 bar-positive">
      <ion-nav-back-button class="button-icon icon  ion-ios7-arrow-back">
        Back
      </ion-nav-back-button>
    </ion-nav-bar>

    <ion-nav-view></ion-nav-view>
     
  <script id="tabs.html" type="text/ng-template">
  <ion-tabs class="tabs-icon-top">

    <ion-tab title="News" icon="icon ion-ios7-paper-outline SS-tab-icon" href="#/tab/news">
      <ion-nav-view></ion-nav-view>
    </ion-tab>

    <ion-tab title="Contact" icon="icon ion-ios7-telephone SS-tab-icon" href="#/tab/contact">
      <ion-nav-view></ion-nav-view>
    </ion-tab>

    <ion-tab title="More" icon="icon ion-navicon-round SS-tab-icon" href="#/tab/more">
      <ion-nav-view></ion-nav-view>
    </ion-tab>

  </ion-tabs>
  </script>

  <script id="more_tab_contents.html" type="text/ng-template">
  <ion-view title="{{title}}">
    <ion-content class="has-header padding">

      <div class="list">
        <a nav-clear class="item item-icon-left" href="#tab/info">
          <i class="icon ion-ios7-information SS-tab-icon"></i>
          Information
        </a>
        <a nav-clear class="item item-icon-left" href="#tab/pictures">
          <i class="icon ion-camera SS-tab-icon"></i>
          Pictures
        </a>
        <a nav-clear class="item item-icon-left" href="#tab/sport">
          <i class="icon ion-ios7-football-outline SS-tab-icon"></i>
          Sports
        </a>
      </div>
    </ion-content>

  </ion-view>
  </script>

  <script id="inside.html" type="text/ng-template">
    <ion-view title="{{title}}">
      <ion-content class="has-header padding">
           <div class="SS_inside_content">
              <h1>{{title}}</h1>

              <ol>
              <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
             <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
             <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
              <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
             <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
             <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
              <li>In faucibus condimentum libero, vel iaculis nibh tristique ac. Nunc vitae urna felis. Praesent lectus ligula, vulputate id dolor at, porttitor pretium nulla. </li>
               </ol>
         </div>
     </ion-content>
    </ion-view>
  </script>

  <script id="" type="text/ng-template">
  </script>

  </body>
</html>

Javascript

var schoolApp = angular.module('schoolApp', ['ionic'])



schoolApp.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider


   // setup an abstract state for the tabs directive
    .state('tab', {
      url: "/tab",
      abstract: true,
      templateUrl: "tabs.html"
    })

   .state('tab.news', {
      url: '/news',
      templateUrl: 'inside.html',
      controller: 'newsCtrl'
    })

 
   .state('tab.contact', {
      url: '/contact',
      templateUrl: 'inside.html',
      controller: 'contactCtrl'
    })



 .state('tab.info', {
      url: '/info',
      templateUrl: 'inside.html',
      controller: 'infoCtrl'
    })


.state('tab.pictures', {
      url: '/pictures',
      templateUrl: 'inside.html',
      controller: 'picturesCtrl'
    })

.state('tab.sport', {
      url: '/sport',
      templateUrl: 'inside.html',
      controller: 'sportCtrl'
    })


.state('tab.more', {
      url: '/more',
      templateUrl: 'more_tab_contents.html',
      controller: 'moreCtrl'
    })

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

});



schoolApp.controller('infoCtrl', function($scope) {
  $scope.title="Information";
  console.log ( 'info' );
})



schoolApp.controller('newsCtrl', function($scope) {
  $scope.title="Latest News";
  console.log ( 'news' );
})



schoolApp.controller('contactCtrl', function($scope) {
  $scope.title="Contacts";
  console.log ( 'contact' );
})



schoolApp.controller('picturesCtrl', function($scope) {
  $scope.title="Pictures";
  console.log ( 'pics' );
})
schoolApp.controller('sportCtrl', function($scope) {
  $scope.title="Sports";
  console.log ( 'sport' );
})

schoolApp.controller('moreCtrl', function($scope) {
  $scope.title="Further content choices";
  console.log ( 'more' );
});

Update issue fixed i think

Further to discussions away from here, and looking at the codepen examples, I have reverted to using named views, which I had done before. However before I was loading my “more” content into the tab view for News - now I’m loading everything from the more page, and the pages it links to, into the named view for that tab - I think this is the way Ionic intend it to be done. So, as you click/tap “more” you get extra menu choices, the choose them and all the time you are still within the more tab, it is still active. Is this the way it should be?

One thing I notice. if I go to ‘more’, then ‘sport’ (within more) - then go to one of the other tabs, then back to more, I get sport, then tap more again and get the more menu options.

A log on each state controller shows (for a different sequence than above but same idea):

news named_views.js:96 (Launch of app)
contact named_views.js:100
more named_views.js:104
more > pics named_views.js:114
news named_views.js:96
more > pics named_views.js:114 FIRST TAP OF MORE - REVISIT IT
more named_views.js:104 TAP IT AGAIN

Revised index.html - just updates shown

  <script id="tabs.html" type="text/ng-template">
  <ion-tabs class="tabs-icon-top">

    <ion-tab title="News" icon="icon ion-ios7-paper-outline SS-tab-icon" ui-sref="tab.news">
        <ion-nav-view name="news-tab"></ion-nav-view>
    </ion-tab>

    <ion-tab title="Contact" icon="icon ion-ios7-telephone SS-tab-icon" ui-sref="tab.contact">
      <ion-nav-view name="contact-tab"></ion-nav-view>
    </ion-tab>

    <ion-tab title="More" icon="icon ion-navicon-round SS-tab-icon" ui-sref="tab.more">
      <ion-nav-view name="more-tab"></ion-nav-view>
    </ion-tab>

  </ion-tabs>
  </script>

  <script id="more_tab_contents.html" type="text/ng-template">
  <ion-view title="{{title}}">
    <ion-content class="has-header padding">

      <div class="list">
        <a nav-clear class="item item-icon-left" ui-sref="tab.info">
          <i class="icon ion-ios7-information SS-tab-icon"></i>
          Information ui-sref
        </a>
        <a nav-clear class="item item-icon-left" ui-sref="tab.pictures">
          <i class="icon ion-camera SS-tab-icon"></i>
          Pictures
        </a>
        <a nav-clear class="item item-icon-left" ui-sref="tab.sport">
          <i class="icon ion-ios7-football-outline SS-tab-icon"></i>
          Sports
        </a>
      </div>
    </ion-content>

  </ion-view>
  </script>

Revised JS

var schoolApp = angular.module('schoolApp', ['ionic'])



schoolApp.config(function($stateProvider, $urlRouterProvider) {
  $stateProvider

   // setup an abstract state for the tabs directive
    .state('tab', {
      url: "/tab",
      abstract: true,
      templateUrl: "tabs.html"
    })


   .state('tab.news', {
      url: '/news',
      views: {
        'news-tab': {
          templateUrl: 'inside.html',
          controller: 'newsCtrl'
        }
      }
    })

  

   .state('tab.contact', {
      url: '/contact',
      views: {
        'contact-tab': {
          templateUrl: 'inside.html',
          controller: 'contactCtrl'
        }
      }
    })



   .state('tab.more', {
      url: '/more',
      views: {
        'more-tab': {
          templateUrl: 'more_tab_contents.html',
          controller: 'moreCtrl'
        }
      }
    })




 .state('tab.info', {
      url: '/info',
      views: {
        'more-tab': {
          templateUrl: 'inside.html',
          controller: 'infoCtrl'
         }
      }
    })



.state('tab.pictures', {
      url: '/pictures',
      views: {
        'more-tab': {
          templateUrl: 'inside.html',
          controller: 'picturesCtrl'
         }
      }
    })

.state('tab.sport', {
      url: '/sport',
      views: {
        'more-tab': {
          templateUrl: 'inside.html',
          controller: 'sportCtrl'
         }
      }
    });


  $urlRouterProvider.otherwise('/tab/news');

}); // end config




schoolApp.controller('newsCtrl', function($scope) {
  $scope.title="Latest news";
  console.log('news');
})
schoolApp.controller('contactCtrl', function($scope) {
  $scope.title="Contact us";
  console.log('contact');
})
schoolApp.controller('moreCtrl', function($scope) {
  $scope.title="More (tabs overflow)";
  console.log('more');
})

schoolApp.controller('infoCtrl', function($scope) {
  $scope.title="Information";
  console.log('more > info');
})

schoolApp.controller('picturesCtrl', function($scope) {
  $scope.title="pictures";
  console.log('more > pics');
})
schoolApp.controller('sportCtrl', function($scope) {
  $scope.title="Sports";
  console.log('more > sports');
});

Re back nav -

<a nav-clear class="item item-icon-left" href="#tab/info">
  <i class="icon ion-ios7-information SS-tab-icon"></i>
  Information
</a>

Removing nav-clear fixed this - I much have copied it from an example without noticing it.


Navigating between multiple views within states
Nav back button on every view