tutorial - AngularJS UI Router $ state recargar solo estado hijo
ui router angularjs tutorial (4)
Como se documenta en la Referencia de API, podemos usar $state.reload
:
$state.reload(state)
Un método que obliga a recargar el estado actual. Todas las resoluciones se vuelven a resolver, los controladores se volvieron a establecer y los eventos se volvieron a activar.
Parámetros:
state
(opcional)
- Un nombre de estado o un objeto de estado, que es la raíz de los resuelve para ser resuelto.
Un ejemplo:
//will reload ''contact.detail'' and ''contact.detail.item'' states
$state.reload(''contact.detail'');
De manera similar, podemos lograrlo con $state.go()
y su parámetro de options
:
$ state.go (a, params, opciones)
...
options
(opcional)
location
...inherit
...relative
notify
...reload
(v0.2.5) - {boolean = false | string | object}, Si es verdadero, forzará la transición aunque no haya cambiado ningún estado o parámetro. Volverá a cargar los resúmenes y las vistas del estado actual y de los estados principales. Si recargar es una cadena (u objeto de estado), el objeto de estado se recupera (por nombre o referencia de objeto); y / la transición vuelve a cargar las resoluciones y vistas para ese estado coincidente y todos sus estados secundarios.
Ejemplo de https://github.com/angular-ui/ui-router/issues/1612#issuecomment-77757224 por 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
Un ejemplo
$state.go(''contact'', {...}, {reload: ''contact.detail''});
Estoy utilizando el enrutador UI para las pestañas de un menú principal, así como para los enlaces dentro de uno de los estados (usuarios). El estado de los usuarios tiene una lista de usuarios y cuando se hace clic en un usuario, quiero recargar solo el estado secundario, pero se está recargando tanto el estado secundario como el estado principal (usuarios).
Aquí está mi código:
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;
});
});
Esta es la función en mi controlador principal (UserController) que se llama cuando se hace clic en un usuario:
this.userTreeClick = function(e) {
contextInfo.setUserKey(e.Key);
contextInfo.setUserName(e.Value);
userCtrl.userKey = e.Key;
$state.forceReload();
};
Entonces, digamos que estaba en el estado usuarios.Grupos de usuarios, cuando hago clic en otro usuario, quiero que solo se recargue el estado de usuarios.Grupos de usuarios. es posible? He buscado una respuesta a través de Google y aquí en StackOverflow, pero no he encontrado nada que sea exactamente igual a lo que estoy tratando de hacer. Cuando hago una pausa para verificar $ state. $ Current.name - el nombre es correcto - users.userGroups, pero recarga todo en lugar de solo el estado secundario. ¡Cualquier ayuda es muy apreciada!
El ui-router actual (0.2.14 y superior) agregó soporte para recargar el estado secundario.
Simplemente ponga $state.go(''your_state'', params, {reload: ''child.state''});
hará el trabajo
Consulte: https://github.com/angular-ui/ui-router/issues/1612 y https://github.com/angular-ui/ui-router/pull/1809/files
Lo he conseguido para que funcione. Utilicé lo que sugirió Radim, pero tuve que agregar el elemento url al estado.
.state(''users.userGroups'', {
url: ''/userGroups/{userTrigger}'',
templateUrl: ''/User/UserGroups'',
controller: ''UserGroupController as userGroupCtrl''
})
y en mi controlador, cuando un usuario hace clic en un enlace, uso $state.transitionTo
:
var params = angular.copy($state.params);
params.userTrigger = params.userTrigger === null ? "" : null;
$state.transitionTo($state.current, params, { reload: false, inherit: true, notify: true });
Sólo un FYI para cualquier otro novato por ahí:
después de agregar la url al
.state
, comencé a tener problemas con mis llamadas a la API. Estaba anteponiendo las urls a los métodos de api con la url en mi.state
. Solo debes asegurarte de tener un líder/
en tus URLs de API:
.factory(''usersInGroup'', function($http) {
return {
get: function(groupName) {
return $http.get(''/api/UserApi/GetInGroup/'' + groupName);
}
}
Vi y aprendí algunas cosas bastante interesantes tratando de salir de esto ...
$state.transitionTo("State Here", {"uniqueRequestCacheBuster": null});
Esto simplemente volverá a cargar el estado secundario que desee. No toda la jerarquía de estados.