I am using UI router for tabs of a main menu as well as for links within one of the states (users). The users state has a list of users and when a user is clicked, I want to reload the child state only, but it is reloading both the child state and the parent state (users).
Here's my code:
app.config(function ($stateProvider, $locationProvider, $urlRouterProvider) { $urlRouterProvider.otherwise("/"); $locationProvider.html5Mode(true); $stateProvider .state('home', { abstract: true, template: '<div ui-view=""></div>', controller: 'HomeController as homeCtrl' }) .state('users', { parent: 'home', url: '/users', templateUrl: '/User/Index', controller: 'UserController as userCtrl', }) .state('users.createUser', { templateUrl: '/User/CreateUser', controller: 'CreateUserController as cuCtrl' }) .state('users.editUser', { templateUrl: '/User/EditUser', controller: 'EditUserController as euCtrl', resolve: { userInfo: function (contextInfo, userData) { return userData.get(contextInfo.getUserKey()); } } }) .state('users.addWebItemsForUser', { templateUrl: '/User/AddWebItemsForUser', controller: 'UserWebItemsController as uwiCtrl' }) .state('users.addReportsForUser', { templateUrl: '/User/AddReportsForUser', controller: 'UserReportsController as urCtrl' }) .state('users.userGroups', { templateUrl: '/User/UserGroups', controller: 'UserGroupController as userGroupCtrl' }) //.state('users.logInWebApp', { // template: '<h3>Logging into web app</h3>', // resolve: { // user: function() { // return { // //companyId: contextInfo.getCustomerKey() // //userId: // //password: // } // } // }, // controller: function() { // // need company code, username and password of user then need to open window with webapp url (will that work?) - do we still want to add this functionality? // } //}) .state('links', { url: '/links', templateUrl: '/Link/Index', controller: 'LinkController as linkCtrl' }) .state('onlrpts', { url: '/onlineReports', templateUrl: '/OnlineReport/Index', controller: 'OnlineReportController as onlRptCtrl' }) .state('reports', { url: '/customerReports', templateUrl: '/CustomerReport/Index', controller: 'CustomerReportController as custRptCtrl' }); }) .config(function($provide) { $provide.decorator('$state', function($delegate, $stateParams) { $delegate.forceReload = function() { return $delegate.go($delegate.$current.name, $stateParams, { reload: true, inherit: false, notify: true }); }; return $delegate; }); });
This is the function in my parent controller (UserController) that is called when a user is clicked:
this.userTreeClick = function(e) { contextInfo.setUserKey(e.Key); contextInfo.setUserName(e.Value); userCtrl.userKey = e.Key; $state.forceReload(); };
So say I was in the users.userGroups state, when I click on another user, I want only the users.userGroups state to be reloaded. Is this possible? I have looked for an answer via Google and here at StackOverflow, but I haven't found anything that is exactly like what I am trying to do. When I break to check the $state.$current.name - the name is correct - users.userGroups, but it reloads everything instead of just the child state. Any help is very much appreciated!
As documented in API Reference , we can use $state.reload
:
$state.reload(state)
A method that force reloads the current state. All resolves are re-resolved, controllers reinstantiated, and events re-fired.
Parameters:
state
(optional)
- A state name or a state object, which is the root of the resolves to be re-resolved.
An example:
//will reload 'contact.detail' and 'contact.detail.item' states $state.reload('contact.detail');
Similar we can achieve with a $state.go()
and its options
parameter:
$state.go(to, params, options)
...
options
(optional)
location
...inherit
...relative
...notify
...reload
(v0.2.5) - {boolean=false|string|object}, If true will force transition even if no state or params have changed. It will reload the resolves and views of the current state and parent states. If reload is a string (or state object), the state object is fetched (by name, or object reference); and \ the transition reloads the resolves and views for that matched state, and all its children states.
Example from https://github.com/angular-ui/ui-router/issues/1612#issuecomment-77757224 by Chris T:
{ reload: true } // reloads all, { reload: 'foo.bar' } // reloads top.bar, and any children { reload: stateObj } // reloads state found in stateObj, and any children
An example
$state.go('contact', {...}, {reload: 'contact.detail'});
The current ui-router (0.2.14 and above) added support to reload child state.
Simply put $state.go('your_state', params, {reload: 'child.state'});
will do the job.
See: https://github.com/angular-ui/ui-router/issues/1612 and https://github.com/angular-ui/ui-router/pull/1809/files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With