Path Variables In Tabs

Hi,

I would like to know what is the correct methodology in using path variables in tabs.

In my application I have a screen (screen 1) which contains a list of items, when each item is clicked they are taken to a tabbed screen which contains data regarding the clicked list item.

However the problem is that when I click on the first item in the list and navigate the tabs it works, however when I click on the second any other item and navigate the tabs the path variable set to the scope is still the value of the first clicked item.

state('app.ticket', {
  url: "/ticket/:ticketId",
  abstract: true,
  views: {
    'menuContent': {
      templateUrl: "app/controller/ticket/detail/ticket-tabs.html",
      controller: 'TicketTabCtrl'
    }
  }
})
.state('app.ticket.info', {
  url: "/info",
  views: {
    'home-tab': {
      templateUrl: "app/controller/ticket/detail/ticket-info.html",
      controller: 'TicketItemCtrl'
    }
  }
})
.state('app.ticket.data', {
  url: "/data",
  views: {
    'data-tab': {
      templateUrl: "app/controller/ticket/detail/ticket-data.html",
      controller: 'TicketItemCtrl'
    }
  }
})
.state('app.ticket.update', {
  url: "/update",
  views: {
    'update-tab': {
      templateUrl: "app/controller/ticket/detail/ticket-update.html",
      controller: 'TicketItemCtrl'
    }
  }
});

With the controller

app.controller('TicketTabCtrl', function($scope, $stateParams, RunTicketService) {
  $scope.ticketId = $stateParams.ticketId;
});

With the tabset

<ion-tab title="Home" icon="ion-home" href="#/app/ticket/{{ticketId}}/info">
    <ion-nav-view name="home-tab"></ion-nav-view>
  </ion-tab>
  <ion-tab title="Data" icon="ion-home" href="#/app/ticket/{{ticketId}}/data">
    <ion-nav-view name="data-tab"></ion-nav-view>
  </ion-tab>
  <ion-tab title="Update" icon="ion-home" href="#/app/ticket/{{ticketId}}/update">
    <ion-nav-view name="update-tab"></ion-nav-view>
  </ion-tab>

The issue is that “$scope.ticketId” is only set during the first list item click and the same “ticketId” value set to the scope is used when any other list items are clicked after the first list item then.

How could I stop the ticketId being persisted and directly access the correct path variable value.

Regards,
Joseph

try

$scope.$on('$ionicView.beforeEnter', function() {
    $scope.ticketId = $stateParams.ticketId;
}

After using “ionicView.beforeEnter” now the “$scope.ticketId = $stateParams.ticketId;” code is run each time the user clicks on a new list element and is navigated to a tab then. Whereas before “$scope.ticketId = $stateParams.ticketId;” would only get executed when the first list element is clicked. HOWEVER now “$stateParams.ticketId” seems to have the value of the first selected list element always instead of the actual list element selected.

Also the “$scope.ticketId = $stateParams.ticketId;” statement is executed twice, once when the list item is clicked (During this stage the displayed screen is still the list). Then again after the user is nagivated to the tab screen (During this stage the displayed screen is the clicked items tab screen). Any idea on why this is happening? Though it is not of primary concern as the other issue of where the ticketId state param is not changing.

Regards,
Joseph

The reason it is called twice is because you defined it in Abstract state Controller, and both of your child states are inherited from it, so it is always called when either of child state is called.

As for why the id never changes it’s difficult to say without a live example.

Maybe refactor your routes and instead of #/app/ticket/{{ticketId}}/info and #/app/ticket/{{ticketId}}/data DO:

/app/ticket/info/{{ticketId}} and /app/ticket/data/{{ticketId}}

This way you can get stateParam.ticketId in individual controller ?

Well I removed it from the abstract state controller and put the code into the child controller. After this each time the tabs screen was loaded the right Id was retireved from the state param. HOWEVER on the rendered links in the tabs html template there was no Id set, the links looked like.

/app/ticket//info

Where as you can notice there is no ticketId set and there then is a set of double forward slashes “//”. This is as the ticketId is set to the scope of the individual tabs and not the abstract parent state controller which controls the rendering of the tabs.

Regards,
Joseph

you can fix it by creating a holding scope variable in abstract controller like so

$scope.viewModel = {}

And then in child controllers

$scope.viewModel.ticketId = ...

and then in html

ng-href="/some/route/{{viewModel.tickedId}}/data"

That solved the issue of the null or empty ticketId in the tab urls. They now appear as



When inspected in google chrome. However let’s say that I viewed my first list item and then view another list item, after clicking the second list item in the list I am directed to the info tab (which is the initial tab). Then proceed to click on the “data” tab, however when I do so the stateParam’s ticketId is “2” where “2” is the ticketId of the first ticket Id visited and the urls ticketIds are rewritten to “2”. Any ideas. I also tried the root scope without much luck. The issue seems to be that the stateParam is not updating appropriately when the id is changed.

Regards,
Joseph

I don’t think you should use :id in abstract state. Just have abstract URL as /ticket and then have /:tickedId as child one, and then a third level child with /data. Try that

Not much luck there either after moving the path variable off the abstract state.

Thereafter I stopped using ‘$ionicView.beforeEnter’ and simply put

$scope.viewModel.ticketId = ...

After doing this and clicking on the “data” tab (for second list item click) the URLS do NOT change when I inspect the html as the viewModel.ticketId is only set once on the child controller load. HOWEVER still when I click a different tab the wrong id is set to the url upon click. It seems something to do with how the url is set with the tab click.

Regards,
Joseph