controller only initialized once even if `$statepa

2019-07-15 08:22发布

问题:

I've recently started working with the Ionic Framework (and therefore with Angular.js as well) and I ran into a problem with the Angular UI Router: One of the states I registered is not re-initialized when one of its $stateParams changes. At first I thought it happens because the state is abstract and has children, so it is never activated directly - but even when I changed it to be non-abstract and one of the "deepest" states (i.e. a leaf when seeing the states within a tree structure), the problem persists. The weird thing is that it seems not to happen on other states.

I have tried different approaches and read the documentation carefully, but I could not find the cause for the issue.

The following is the code I use to register the states. The state app.festival is the one I'm having the issue with:

  • when I link to the app.festival.overview state for the first time, for example with URL /festival/33/overview, the the state's controller as well as its abstract parent controller for app.festival are initialized correctly
  • but then, when I go back somewhere else, and then link to something like /festival/21/overview, only this state's controller is re-initialized, but not its abstract parent controller (although the parameter for the festivalId is part of it and should trigger a reload I suppose)
  • this results in the actual festival data (referenced by festivalId) which is managed by the app.festival state remains the same throughout the entire app because basically it just initializes one "instance" of the controller for app.festival regardless of different $stateParams

The reason I need that structure is that there needs to be a whole section of pages (states) that deal with a single festival (which should be managed by the app.festival state).

$stateProvider

.state( 'app', {
    url: '',
    abstract: true,
    views: {
        'appContent': {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        }
    }
})

.state( 'app.general', {
    url: '/general',
    abstract: true,
    views: {
        'mainContent': {
            templateUrl: 'views/sections/general.html',
            controller: 'GeneralCtrl'
        }
    }
})

.state( 'app.festival', {
    url: '/festival/{festivalId:int}',
    abstract: true,
    views: {
        'mainContent': {
            templateUrl: 'views/sections/festival.html',
            controller: 'FestivalCtrl'
        }
    }
})

.state( 'app.general.festivals', {
    url: '/festivals',
    views: {
        'generalContent': {
            templateUrl: 'views/pages/general-festivals.html',
            controller: 'GeneralFestivalsCtrl'
        }
    }
})

.state( 'app.general.events', {
    url: '/events',
    views: {
        'generalContent': {
            templateUrl: 'views/pages/general-events.html',
            controller: 'GeneralEventsCtrl'
        }
    }
})

.state( 'app.general.event', {
    url: '/events/{eventId:int}',
    views: {
        'generalContent': {
            templateUrl: 'views/pages/general-event.html',
            controller: 'GeneralEventCtrl'
        }
    }
})

.state( 'app.festival.overview', {
    url: '/overview',
    views: {
        'festivalContent': {
            templateUrl: 'views/pages/festival-overview.html',
            controller: 'FestivalOverviewCtrl'
        }
    }
});

.state( 'app.festival.guide', {
    url: '/guide',
    views: {
        'festivalContent': {
            templateUrl: 'views/pages/festival-guide.html',
            controller: 'FestivalGuideCtrl'
        }
    }
});

It would be great if anyone could help me out there as I've put quite some hours into researching the issue, but have not found a solution yet. If you need more insight into specific parts of the code, I'll gladly post it here as well.

回答1:

This is the default behaviour of Ionic. It by default caches view and controller execution to improve performance. You can disable it with cache: false:

$stateProvider.state('myState', {
   cache: false,
   url : '/myUrl',
   templateUrl : 'my-template.html'
});

Or you can disable it at URL level using ui-sref-opts how to put reload option in ui-sref markup

See Caching docs.