Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller executing twice with ui-router nested states (Ionic)

Problem

My Ionic app lets you choose a Project from the side menu, and then displays two tabs (Tasks, Messages) in the main content area. The tasks and messages tabs are nested states of project.

When you change projects in the side menu, TaskListCtrl gets executed twice. See the live demo and watch the console as you change between projects. I also have a video which shows the issue in detail.

How do I stop TaskListCtrl from executing twice? Is there a better way I could be structuring these nested states?

Code

Full code is on GitHub »

Here's my $stateProvider config:

.state('project', {
  url: "/projects/:projectID",
  abstract: true,
  cache: false,
  controller: 'ProjectDetailCtrl',
  templateUrl: "templates/project.tabs.html",
  resolve: {
    project: function($stateParams, Projects) {
      return Projects.get($stateParams.projectID);
    }
  }
})

.state('project.tasks', {
  url: '/tasks',
  views: {
    'tasks-tab': {
      templateUrl: 'templates/task.list.html',
      controller: 'TaskListCtrl'
    }
  }
})

And the relevant snippet from controllers.js:

.controller('ProjectDetailCtrl', function($scope, project) {
  $scope.project = project;
  console.log('=> ProjectDetailCtrl (' + $scope.project.name + ')')
})

.controller('TaskListCtrl', function($scope, $stateParams) {
  $scope.tasks = $scope.project.tasks;

  console.log('\t=> TaskListCtrl')
  console.log('\t\t=> $stateParams: ', $stateParams)
  console.log('\t\t=> $scope.tasks[0].title: ', $scope.tasks[0].title)
})

Resources

  • Live demo (watch the console logs as you change between projects)
  • Video showing the issue
  • Code on GitHub

Notes

  • I am aware there are similar questions on StackOverflow — however, none of the solutions they offer solved my issue.*
  • I've read this can happen when attaching the controller both in $stateProvider and with ng-controller — however, I've checked and I'm not doing this. I'm only attaching the controller with $stateProvider.
like image 709
Kyle Fox Avatar asked Nov 10 '22 09:11

Kyle Fox


1 Answers

I guess tuckerjt07 is right.

It seems to be an issue with routing and parameters and ionic tabs. I've spend almost the whole day trying to figure out what is going on.

I thought the problem was with the fact you're using an abstract controller with parameters, but that's not the problem.

I've checked if the side menu was interfering with tabs but, again, the problem is not there.

I've checked the scope trying to eliminate friction using controllerAs and avoiding to reference the $scope object to store the viewmodel but ... nothing.

I've created a simplified version of your application here.
There's not much in there and the navigation is through constants in the header. As you can see the problem is still there.

Doing a little bit of debugging it seems that the problem sits here.
That line calls the controller twice. You can check it yourself adding a breakpoint at line 48435 in ionic.bundle.js.

The only option you have is to change your project.tabs.html and load the list of tasks without the sub-view. Something like this:

<ion-view view-title="{{ project.name }}: Tasks">

<ion-tabs class="tabs-icon-top tabs-positive">

  <ion-tab title="{{ project.name }} Tasks" icon="ion-home">

    <ion-nav-view>
      <ion-content>
        <ion-list>
          <ion-item class="item-icon-right" ng-repeat='task in project.tasks'>
            {{ task.title }}
            <i class="icon ion-chevron-right icon-accessory"></i>
          </ion-item>
        </ion-list>
      </ion-content>
    </ion-nav-view>

  </ion-tab>

  <ion-tab title="About" icon="ion-ios-football" ui-sref="tabs.tab2">
    <ion-nav-view name="tabs-tab2"></ion-nav-view>
  </ion-tab>

  <ion-tab title="Another" icon="ion-help-buoy" ui-sref="tabs.tab3">
    <ion-nav-view name="tabs-tab3"></ion-nav-view>
  </ion-tab>

</ion-tabs>

</ion-view>

You can check how it works here.

I guess we should open an issue.

like image 117
LeftyX Avatar answered Nov 28 '22 00:11

LeftyX