Disons que j'ai les 3 Angular UI Router states suivants:
$stateProvider
.state('adminCompanies', {
abstract: true,
url: "/admin/companies",
template: '<div ui-view class="viewContainer" autoscroll="false" />'
})
.state('adminCompanies.list', {
url: "",
templateUrl: 'app/admin/companies/companies.list.html',
controller: 'AdminCompaniesController'
})
.state('adminCompanies.detail', {
url: "/:companyId",
templateUrl: 'app/admin/companies/companies.detail.html',
resolve: {
company: function(Model, $stateParams) {
return Model.get("/admin/companies", $stateParams.companyId);
}
},
controller: 'AdminCompanyDetailController'
})
Si le adminCompanies
est transféré directement, comment dire à Angular UI Router d'aller au adminCompanies.list
à la place?
Idéalement, ce que j'aimerais, c'est quelque chose comme:
$stateProvider.when('adminCompanies', 'adminCompanies.list');
Dans mon code, je veux que $ state.go ('adminCompanies') soit équivalent à $ state.go ('adminCompanies.list')
Comme votre application est actuellement configurée, vous ne devriez pas avoir besoin de logique explicite pour cela. Lorsqu'un sous-état a une propriété url
vide, il devient actif en même temps que son état parent devient actif. Tout modèle de sous-état est inséré dans le ui-view
directive fournie par le modèle de l'État parent. L'interface utilisateur Angular exemple d'application traite ce type d'architecture: lorsque l'état contacts
est parcouru, son modèle fournit la disposition de la navigation ainsi qu'un ui-view
pour ses sous-états; parce que le contacts.list
l'état a une propriété url
de ""
, il est automatiquement chargé lorsque son état parent, contacts
est parcouru. Ceci est documenté dans les commentaires de l'application:
L'utilisation d'une URL vide signifie que cet état enfant deviendra actif lorsque l'URL de son parent sera parcourue. Les URL des états enfants sont automatiquement ajoutées aux URL de leurs parents. L'URL de cet état est donc '/ contacts' (car '/ contacts' + '').
Maintenant, en supposant pour une raison ou une autre que vous vous n'avez jamais voulu que l'état parent adminCompanies
devienne actif. Dans ce cas, vous pouvez faire de cet état un état abstrait comme ceci:
$stateProvider
.state('adminCompanies', {
abstract: true,
url: "/admin/companies",
template: '<div ui-view class="viewContainer" autoscroll="false" />'
})
.state('adminCompanies.list', {
url: "/list",
templateUrl: 'app/admin/companies/companies.list.html',
controller: 'AdminCompaniesController'
})
.state('adminCompanies.detail', {
url: "/:companyId",
templateUrl: 'app/admin/companies/companies.detail.html',
resolve: {
company: function(Model, $stateParams) {
return Model.get("/admin/companies", $stateParams.companyId);
}
},
controller: 'AdminCompanyDetailController'
})
Notez l'ajout de abstract: true
ajout sur la 3ème ligne et l'URL d'état explicite de /list
pour adminCompanies.list
Cela indique à Angular-UI qu'il doit traiter cet état comme s'il n'existait pas à des fins de navigation URL. Cependant, il restera actif lorsque vous naviguerez vers des sous-états, il utilisera donc toujours l'URL que vous fournissez pour préfixer l'URL des sous-états. Mais si vous essayez d'y accéder à partir d'un autre état, cela agira comme si l'état n'existait pas. Pour cette raison, vous devrez également ajouter la gestion des URL sans correspondance à l'aide de $urlRouteProvider
.
Une utilisation basique de $urlRouteProvider
pourrait ressembler à ceci:
$urlRouterProvider.otherwise("/")
Cela redirige simplement tous les appels vers des états inexistants vers l'état avec l'URL "/". Cela suppose que vous en avez un. Cependant, parce que quelqu'un essaie peut-être d'accéder à la vue liste mais navigue vers /admin/companies
directement, vous devriez probablement avoir un gestionnaire comme celui-ci:
$urlRouterProvider.when("/admin/companies", "/admin/companies/list");
Celui que vous utilisez dépend de l'architecture de votre application, mais il semble que pour vos besoins actuels, vous ne devriez rien faire. Si vos spécifications changent, l'état abstrait pourrait être utile.
Vous pouvez également utiliser i-router-default - un module où les états enfants par défaut sont définis dans l'état parent en définissant abstract: ".defaultChild"
.
Cela a l'avantage de pouvoir utiliser ui-sref="parent"
Et $state.go("parent");
(ce qui était important pour moi lors de la création dynamique d'une barre de navigation).
NB: ceci et la solution de David ne fonctionnent que si l'état parent est abstrait - c'est-à-dire que le parent ne peut pas être actif sans qu'un enfant soit actif - ce qui devrait être le cas lorsque nous voulons avoir une vue enfant "par défaut".
(Voir aussi la discussion pertinente de l'équipe ui-router ici .)
Dans la version 1.0.0alpha0 ils le rendent enfin possible! Pas enfant pour les états abstraits, nouveau $ transitionsProvider , dans lequel vous pouvez définir onBefore crochet. Vous pouvez modifier le comportement en fonction des options d'état.
Par exemple, vous pouvez modifier le comportement du paramètre "abstrait":
$transitionsProvider.onBefore({
to: state => !!state.abstract
}, ($transition$, $state) => {
if (angular.isString($transition.to().abstract)) {
return $state.target($transition.to().abstract);
}
});
et l'utiliser comme ça:
abstract: 'abstract2.foo', //use not boolean but exact child state
provient de: i-router: enfant par défaut pour l'état abstrait