javascript - template - Dirigir al usuario a un estado hijo cuando están en transición a su estado principal usando UI-Router
ui-router angular 6 (9)
Considera lo siguiente:
.state(''manager.staffList'', {url:''^/staff?alpha'', templateUrl: ''views/staff.list.html'', data:{activeMenu: ''staff''}, controller: ''staffListCtrl''})
.state(''manager.staffDetail'', {url:''^/staff/{id}'' , templateUrl: ''views/staff.html'', data:{activeMenu: ''staff''}, controller: ''staffDetailsCtrl''})
.state(''manager.staffDetail.view'', {url:''/view'', templateUrl: ''views/staff.details.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.schedule'', {url:''/schedule'', templateUrl:''views/staff.view.schedule.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.history'', {url:''/history'' , templateUrl:''views/staff.view.history.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.log'', {url:''/log'', templateUrl:''views/staff.view.log.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.files'', {url:''/files'', templateUrl:''views/staff.view.files.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.edit'', {url:''/edit'', templateUrl: ''views/staff.edit.html'', data:{activeMenu: ''staff''}})
Si voy a domain.com/staff/1234/view
, ¿cómo configuro de forma predeterminada el estado hijo de manager.staffDetail.view.schedule
?
Primero, agregue una propiedad al estado de
abstract:true
''manager.staffDetail.view''
abstract:true
. Esto no es obligatorio, pero desea configurar esto ya que nunca iría directamente a este estado, siempre iría a uno de sus estados hijos.Luego, haga una de las siguientes cosas:
''manager.staffDetail.view.schedule''
estado''manager.staffDetail.view.schedule''
una URL vacía . Esto hará que coincida con la misma URL que su url padre de estado, ya que no agrega nada a la url principal..state(''manager.staffDetail.view.schedule'', {url:'''', ...
O si desea mantener sin cambios la url de la ruta hija predeterminada, configure una redirección en su module.config. Este código aquí redirigirá cualquier ubicación de
''/staff/{id}/view''
a la ubicación de''/staff/{id}/view/schedule''
:$urlRouterProvider.when(''/staff/{id}/view'', ''/staff/{id}/view/schedule'');
Agregue angular-ui-router-default y agregue las opciones abstract
y default
al estado primario:
...
.state(''manager.staffDetail.view'', {abstract: true, default: ''.schedule'', url:''/view'', templateUrl: ''views/staff.details.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.schedule'', {url:''/schedule'', templateUrl:''views/staff.view.schedule.html'', data:{activeMenu: ''staff''}})
...
Nota: para que esto funcione, la plantilla padre debe tener <ui-view/>
en algún lugar de ella.
Cambié ''manager.staffDetial.view'' a un estado abstracto y dejé la url de mi estado secundario predeterminado en blanco ''''
// Staff
.state(''manager.staffList'', {url:''^/staff?alpha'', templateUrl: ''views/staff.list.html'', data:{activeMenu: ''staff''}, controller: ''staffListCtrl''})
.state(''manager.staffDetail'', {url:''^/staff/{id}'', templateUrl: ''views/staff.html'', data:{activeMenu: ''staff''}, controller: ''staffDetailsCtrl''})
.state(''manager.staffDetail.view'', {url:''/view'', abstract: true, templateUrl: ''views/staff.details.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.schedule'', {url:'''', templateUrl:''views/staff.view.schedule.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.history'', {url:''/history'', templateUrl:''views/staff.view.history.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.log'', {url:''/log'', templateUrl:''views/staff.view.log.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.view.files'', {url:''/files'', templateUrl:''views/staff.view.files.html'', data:{activeMenu: ''staff''}})
.state(''manager.staffDetail.edit'', {url:''/edit'', templateUrl: ''views/staff.edit.html'', data:{activeMenu: ''staff''}})
En "angular-ui-router": "0.2.13", no creo que la solución de redireccionamiento de @nfiniteloop funcione. Funcionó una vez que había retrocedido a 0.2.12 (y puede haber tenido que poner la llamada $ urlRouterProvider.when antes del $ stateProvider?)
ver https://.com/a/26285671/1098564
y https://.com/a/27131114/1098564 para una solución alternativa (si no desea volver a 0.2.12)
a partir del 28 de noviembre de 2014, https://github.com/angular-ui/ui-router/issues/1584 indica que debería funcionar nuevamente en 0.2.14
Esto es tarde, pero todas las respuestas aquí no se aplican a la última versión de angular-ui-router para AngularJS. A partir de esa versión (específicamente @uirouter/angularjs#v1.0.x puedes simplemente poner redirectTo: ''childStateName''
en el segundo $stateProvider.state()
de $stateProvider.state()
. Por ejemplo:
$stateProvider
.state(''parent'', {
resolve: {...},
redirectTo: ''parent.defaultChild''
})
.state(''parent.defaultChild'', {...})
Aquí está la sección correspondiente del documento: https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-hook-redirectto
¡Espero que esto ayude a alguien!
Me encontré con el mismo problema y encontré que esta solución funciona:
https://github.com/angular-ui/ui-router/issues/948#issuecomment-75342784
Esto es citado de @christopherthielen en github
"Por ahora, no declare el resumen de su estado y use esta receta:"
app.run($rootScope, $state) {
$rootScope.$on(''$stateChangeStart'', function(evt, to, params) {
if (to.redirectTo) {
evt.preventDefault();
$state.go(to.redirectTo, params)
}
});
}
$stateProvider.state(''parent'' , {
url: "/parent",
templateUrl: "parent.html",
redirectTo: ''parent.child''
});
$stateProvider.state(''parent.child'' , {
url: "/child",
templateUrl: "child.html"
});
Aquí está el desglose de cómo funciona el proceso:
- El usuario navega para indicar "padre"
- El evento "$ stateChangeStart" se activa
- El oyente de "$ stateChangeStart" atrapa el evento y pasa "toState" (que es "parent") y "event" a la función del manejador
- La función del manejador verifica si "redirectTo" está configurado en "toState".
- Si "redirectTo" NO está configurado, no ocurre nada y el usuario continúa al estado "toState".
- Si se establece "redirectTo", el evento se cancela (event.preventDefault) y $ state.go (toState.redirectTo) los envía al estado especificado en "redirectTo" (que es "parent.child").
- El evento "$ stateChangeStart" se activa nuevamente, pero esta vez "toState" == "parent.child" y la opción "redirectTo" no está configurada, por lo que continúa en "toState".
Muy tarde, pero creo que puedes "redirigir" al estado que deseas.
.state(''manager.staffDetail.view'', {
url:''/view'',
templateUrl: ''views/staff.details.html'',
controller: ''YourController''
})
app.controller(''YourController'', [''$state'',
function($state) {
$state.go(''manager.staffDetail.view.schedule'');
}]);
Puedes escribir tu controlador directamente en la configuración de estado para abreviar.
Para configurar la vista infantil predeterminada, consulte este example . Al hacer clic en Route 1
cargar el estado predeterminado route1.list
// For any unmatched url, send to /route1
$stateProvider
.state(''route1'', {
url: "/route1",
abstract:true ,
templateUrl: "route1.html"
})
.state(''route1.list'', {
url: '''',
templateUrl: "route1.list.html",
controller: function($scope){
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state(''route1.desc'', {
url: "/desc",
templateUrl: "route1.desc.html",
controller: function($scope){
$scope.items = [];
}
})
.state(''route2'', {
url: "/route2",
templateUrl: "route2.html"
})
.state(''route2.list'', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($scope){
$scope.things = ["A", "Set", "Of", "Things"];
}
})
aquí hay una alternativa muy simple y transparente simplemente modificando el estado padre en el enrutador ui:
.state(''parent_state'', {
url: ''/something/:param1/:param2'',
templateUrl: ''partials/something/parent_view.html'', // <- important
controller: function($state, $stateParams){
var params = angular.copy($state.params);
if (params[''param3''] === undefined) {
params[''param3''] = ''default_param3'';
}
$state.go(''parent_state.child'', params)
}
})
.state(''parent_state.child'', {
url: ''/something/:param1/:param2/:param3'',
templateUrl: ''....'',
controller: ''....''
})