web-dev-qa-db-fra.com

Comment utiliser Angular Onglets ui.bootstrap avec ui.router?

Voici ma mise en œuvre initiale des onglets ui.bootstrap en utilisant ui.router:

<tabset>
  <tab heading="Tab1" select="$state.go('home.tab1')">
    <div ui-view="forTab1"></div>
  </tab>
  <tab heading="Tab2" select="$state.go('home.tab2')">
    <div ui-view="forTab2"></div>
  </tab>
</tabset>

Joliment simple, et cela fonctionne principalement, mais il a plusieurs problèmes.

Premièrement, cela ne fonctionne pas si je saisis une URL dans le navigateur, par exemple. ".../home/tab1". Le problème que je suppose est que, bien que ui.router puisse acheminer le routage vers la vue correcte, il ne sait pas comment sélectionner l'onglet de cette vue.

Deuxièmement, si j'essaie de laisser la page pour un état sur une autre page, cela déclenche un bogue apparent dans la logique des onglets. Lorsque l'ensemble d'onglets est en cours de destruction, les onglets sont détruits un par un. Lorsqu'il détruit l'onglet actuellement sélectionné, il semble exécuter la même logique que si elle était exécutée uniquement si cet onglet était détruit, et non pas le jeu complet d'onglets. Cela le force à sélectionner l'un des autres onglets non encore détruits, ce qui oblige ui.router à passer à l'état de cet onglet, ce qui m'empêche de quitter la page. (La solution devrait être que la destruction du jeu d'onglets ne devrait pas sélectionner d'onglets pendant le processus de destruction.)

Troisièmement, certains des onglets peuvent être complexes, avec de nombreux accès au serveur lors de leur construction. Je ne veux pas les détruire et les recréer chaque fois que je passe d'un onglet à un autre. Je préférerais de beaucoup créer un onglet lorsque cet onglet est sélectionné pour la première fois, puis persister jusqu'à ce que je quitte la page. La sélection d'un onglet précédemment affiché devrait simplement le rendre à nouveau visible, pas le recréer.

Donc, il me semble avoir besoin de quelque chose de plus complexe et sophistiqué, mais quoi? Merci d'avance pour toute suggestion.

Mise à jour: ui.router FAQ pose une question sur la manière de mettre en œuvre des onglets. Il pointe vers un package "extras" qui semble prometteur. J'espère qu'il y a un moyen d'intégrer les onglets ui.bootstrap. http://christopherthielen.github.io/ui-router-extras/#/sticky

Mise à jour: voici deux implémentations qui fonctionnent beaucoup mieux mais qui ne sont toujours pas tout à fait correctes. Le premier utilise les onglets ui.bootstrap:

<tabset>
  <tab heading="Products" ui-sref=".products" active="$state.includes('home.products')"></tab>
  <tab heading="Users" ui-sref=".users" active="$state.includes('home.users')"></tab>
</tabset>
<div ui-view="home.products" ng-show="$state.includes('home.products')"></div>
<div ui-view="home.users" ng-show="$state.includes('home.users')"></div>

La seconde est basée sur top.html de l'exemple de sticky-tabs de Chris Thielen:

<div class="navbar navbar-default navbar-static-top" role="navigation">
  <ul class="nav navbar-nav">
    <li ng-class="{active: $state.includes('home.products')}" ><a ui-sref="home.products">Products</a></li>
    <li ng-class="{active: $state.includes('home.users')}" ><a ui-sref="home.users">Users</a></li>
  </ul>
</div>
<div class="tabcontent well-lg" ui-view="home.products" ng-show="$state.includes('home.products')" class="col-sm-6"></div>
<div class="tabcontent well-lg" ui-view="home.users"    ng-show="$state.includes('home.users')"    class="col-sm-6"></div>

Ces deux solutions évitent mes deux premiers problèmes ci-dessus - accéder à un onglet via une URL fonctionne, et je peux quitter la page sans déclencher le bogue de destruction des onglets (probablement parce que je n'utilise pas "select ="). 

Cependant, il y a toujours un problème, et cela se produit avec les deux versions. Le modèle home.users a une grille ui et si je vais d'abord sur la page avec cet onglet sélectionné, la grille est vide. Je peux voir le client demander les données de la grille au serveur, mais il ne l'affiche pas. Si je vais à l'autre onglet et que je reviens, il affichera les données (après les avoir relues). Pire encore, cela signifie que je ne peux pas rendre le message home.users collant, car il reste bloqué dans le mode sans affichage de données.

13
Franz Amador

Le moyen le plus simple est d'ignorer toutes les directives sophistiquées de ui-bootstrap et d'utiliser simplement le CSS. Ensuite, vous pouvez vous retrouver avec quelque chose de très simple:

<ul class="nav nav-tabs">
    <li ui-sref=".state1" ui-sref-active="active"><a>State 1</a></li>
    <li ng-repeat="type in viewModel.types"
        ui-sref=".typeState({type:type})"
        ui-sref-active="active"><a>{{type}}</a></li>
</ul>

Cela donnera l'apparence des onglets tout en maintenant un état actif correct. Le problème avec l'utilisation de la directive <tab-header> est qu'il est impossible d'initialiser proprement l'état actif à partir du routeur ui $state, de sorte que plusieurs onglets sont mis en surbrillance au chargement de la page.

24
srlm

Vous pouvez envisager de jeter un coup d’œil à ce projet, routeur ui plus les onglets d’amorçage ui , qui se déclare comme 

Volets à onglets insensés avec prise en charge du routage avec Angular.js + Bootstrap 3 + UI Router

Je ne l'ai pas encore essayée, mais ça a l'air prometteur.

5
ElliotPsyIT

Je viens de faire cela dans un de mes projets. Cela suppose que vos itinéraires sont câblés avec ui.router. J'espère que ça aide.

<uib-tabset active="active">

    <uib-tab index="0" ui-sref ="tab1" heading="Tab1"></uib-tab>

    <uib-tab index="1" ui-sref="tab2" heading="Tab2"></uib-tab>

</uib-tabset>

1
dlsdaviddls