James Crinkley
James Crinkley

Reputation: 1398

Angular UI Router - Prevent re-running of parent state when switching between children

I currently have a state hierarchy in my application like so;

- module_base
    - page_base
        - tab_one
        - tab_two
        - tab_three

The page_base state is abstract and has a Controller that returns the record for the page (e.g. GET /products/123) and that is then accessible to the child tabs.

The problem I'm having is that when transitioning between the tabs above the Controller for the page_base state re-runs every time, meaning that the product resource is retrieved on every transition.

The menu for navigating between tabs is just a list of <a/>s with a ui-sref (e.g. <a ui-sref=".tab_one">Tab One</a>). I have looked into the reload and notify parameters using ui-sref-opts but they seem to make no difference.

How can I force the page_base state to only load once when on page /products/3/* but ensure that it will re-run when on page products/9/*?

Also, is it possible to have tab_* load once when first opened, but not reload if they are revisited?

Many thanks!

State Configuration;

// Page Base
.state('module_base.page_base', {
    abstract: true,
    url: '/{id:int}',
    views: {
        base: {
            templateUrl: 'path/to/baseTemplate.html',
            controller: 'BaseController', // Reruns whenever the child states are loaded
            controllerAs: 'baseVm'
        },
        'sidebar': {
            // Configuration for the app sidebar
        }
    },
    resolve: {
        // ACL permissions check
    }
})


// Tab one
.state('module_base.page_base.tab_one', {
    url: '/tab-one',
    views: {
        'page': {
            templateUrl: 'path/to/template.html',
            controller: 'TabOneController',
            controllerAs: 'vm'
        }
    }
})

// Tab two
.state('module_base.page_base.tab_two', {
    url: '/tab-two',
    views: {
        'page': {
            templateUrl: 'path/to/template.html',
            controller: 'TabTwoController',
            controllerAs: 'vm'
        }
    }
}) 

Upvotes: 1

Views: 407

Answers (2)

James Crinkley
James Crinkley

Reputation: 1398

The cause of this actually turned out to be higher up in the state hierarchy. Between each state transition an ACL permissions check was taking place, and during this process a $rootScope variable was being set to false during the check, then updated to true once resolved. The main application container had a ng-if="$root.userIsAuthorised" which removed the entire app from the DOM, then re-added it. This caused all of the routing to re-run and in turn the controllers to re run.

In short, the fix was to use ng-show / ng-hide to handle hiding without removing from the DOM and the controllers ran as expected.

Upvotes: 1

miqe
miqe

Reputation: 3369

i think if that is what you want then you shouldn't use separate controller for the child tabs. so try removing controller and controllerAs properties from the state. by doing this, the parent/child (shared) controller gets loaded once.

Upvotes: 0

Related Questions