14

Come aggiungere animazioni di dissolvenza a un set di tabulazioni utilizzando angular-ui-bootstrap?Effetto dissolvenza per le schede in ui-bootstrap (Angular.JS)

Ad esempio, dato il codice seguente:

<tabset> 
    <tab heading="Tab1">Some content</tab> 
    <tab heading="Tab2">Other content</tab> 
</tabset> 

Vorrei il contenuto delle schede a svanire quando si passa tra loro. Ho provato ad aggiungere la classe fade ai tag tab (simile a come faresti con il file js di bootstrap3), ma non ha funzionato.

Grazie mille!

+0

Prova a leggere la documentazione per $ animate - forse ti darà un'idea. – lort

+0

Lo farò ... Spero che ci sia una soluzione rapida che ho trascurato, dato che con bootstrap3 js è piuttosto facile da fare – urish

risposta

26

Dal momento che il set di tabulazioni usa ng-class per controllare la scheda "attiva", che ci consente di definire l'effetto di dissolvenza con l'animazione angolare impostando l'opacità = 0 quando la classe "attiva" viene rimossa/allegata.

Innanzitutto, è necessario caricare il modulo ngAnimate includendo angular-animate.js e impostare la dipendenza.

Aggiungi alla tua <head>: modulo

<script src="https://code.angularjs.org/1.2.24/angular-animate.js"></script> 

Set dipendenza:

angular.module("myApp", ["ui.bootstrap", "ngAnimate"]); 

Ora Aggiungi classe di animazione al vostro tabset.

<tabset class="tab-animation"> 
    <tab heading="Tab1">Some content</tab> 
    <tab heading="Tab2">Other content</tab> 
</tabset> 

Put seguente codice nel file css:

/* set reference point */ 
.tab-animation > .tab-content { 
    position: relative; 
} 

/* set animate effect */ 
.tab-animation > .tab-content > .tab-pane{ 
    transition: 0.2s linear opacity; 
} 

/* overwrite display: none and remove from document flow */ 
.tab-animation > .tab-content > .tab-pane.active-remove { 
    position: absolute; 
    top: 0; 
    width: 100%; 
    display: block; 
} 

/* opacity=0 when removing "active" class */ 
.tab-animation > .tab-content > .tab-pane.active-remove-active { 
    opacity: 0; 
} 

/* opacity=0 when adding "active" class */ 
.tab-animation > .tab-content > .tab-pane.active-add { 
    opacity: 0; 
} 

Questo è tutto. È possibile controllare lo demo on Plunker.

Anche dare un'occhiata a ngAnimate doc.

2

Ho finito per applicare patch al file ui-bootstrap. Sono ancora un noob con AngularJS, quindi per favore perdona il gergo. Questo è un hack non convenzionale, e deve essere refactored con ng-animate, ma funziona.

aperto ui-bootstrap-TPLS-0.10.0.js e cerca la 'scheda' direttiva:

.directive('tab', ['$parse', function($parse) { 
    return { 
    require: '^tabset', 
    restrict: 'EA', 
    replace: true, 
    templateUrl: 'template/tabs/tab.html', 
    transclude: true, 
    scope: { 
    id:'@', // PATCH : GETTING TAB 'id' ATTRIBUTE 
    heading: '@', 
    onSelect: '&select', //This callback is called in contentHeadingTransclude 
         //once it inserts the tab's content into the dom 
    onDeselect: '&deselect' 
    }, 
    // ... 

Avviso il codice aggiuntivo per recuperare il valore di attributo id (via inclusione, immagino).



Poche righe sotto, cercare:

 scope.$watch('active', function(active) { 

e patch in questo modo:

  scope.$watch('active', function(active) { 
     // Note this watcher also initializes and assigns scope.active to the 
     // attrs.active expression. 
     setActive(scope.$parent, active); 

     if (active) { 
     tabsetCtrl.select(scope); 
     scope.onSelect(); 

     tab_id = attrs.id; 
     $(".tab_pane_"+tab_id).hide(); // HIDE AT FIRST, SO IT CAN ACTUALLY FADE IN 
     $(".tab_pane_"+tab_id).fadeIn(1000); // JQUERY TARGETING BY CLASS 

     } else { 
     scope.onDeselect(); 

     tab_id = attrs.id; 
     $(".tab_pane_"+tab_id).hide(); // JQUERY TARGETING BY CLASS 
     } 

    }); 



Poche righe sotto, guarda per:

scope.select = function() { 

e aggiungere all'interno:

$(".tab-pane").hide(); 

così tutti i riquadri della scheda nascondere correttamente in un primo momento.



Poi, cercare:

angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) { ... 

e aggiungere la classe CSS all'elemento scheda-riquadro del corrispondente modello, in questo modo:

angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) { 
$templateCache.put("template/tabs/tabset.html", 
"\n" + 
"<div class=\"tabbable\">\n" + 
" <ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" + 
" <div class=\"tab-content\">\n" + 
" <div class=\"tab-pane tab_pane_{{tab.id}}\" \n" + // CLASS NAME IS DYNAMIC 
"   ng-repeat=\"tab in tabs\" \n" + 
"   ng-class=\"{active: tab.active}\"\n" + 
"   tab-content-transclude=\"tab\">\n" + 
" </div>\n" + 
" </div>\n" + 
"</div>\n" + 
""); 
}]); 





Una volta che l'ui-bootstrap.il file js viene modificato, è necessario modificare il modello di vista (in cui si recupera lo schede) e dichiarare l'attributo 'id':

<!-- TABS --> 
    <tabset justified="true"> 
     <tab ng-repeat="tab in tabs" heading="{{tab.title}}" id="{{tab.id}}" > 
      // ... TAB CONTENT 



si dovrebbe ottenere il concetto di base, attualmente non è molto elegante (per mettilo mite). Ma funziona.


Nel caso in cui ci si chiede come i miei schede ottenuto id, beh, li ho iniettato nel mio controller:

     Tab1 = { 
         id:1, 
         'ShortDescription': ShortDescription, 
         'FullDescription': FullDescription, 
         'TabContent': TabContent1, 
         title: "ProductTabTitleDefault1", 
         // active:true 
        }; 

        Tab2 = { 
         id:2, 
         'ShortDescription': ShortDescription, 
         'FullDescription': FullDescription, 
         'TabContent': TabContent1, 
         title: "ProductTabTitleDefault2", 
         // active:true 
        }; 


        $rootScope.tabs = { 
         'Tab1': Tab1, 
         'Tab2': Tab2, 
         }; 

Naturalmente si tratta di dati mockup, ma assumendo le schede e il loro contenuto sono dinamici, è puoi usare un contatore e magari usare un altro tasto invece di "id" (ma dovrai cambiare il resto di conseguenza).

+0

Ottima risposta. Semplice da seguire e funziona davvero –

+0

Mescolare jQuery in un progetto angolare non è il modo migliore per farlo. –

0

Ho una soluzione alternativa alla soluzione ben scritta di @ user3413125 qui sopra. Esso utilizza @keyframes per ottenere una dissolvenza incrociata, piuttosto che un fade out seguita da una dissolvenza a See demo on Plunker

Ecco la parte di fade-in del CSS (fade-out è simile):.

.tab-animation > .tab-content > .tab-pane.active-add { 
    animation: 1s fade-in; 
} 

@keyframes fade-in { 
    from { opacity: 0; } 
    to { opacity: 1; } 
} 

La tecnica del fotogramma chiave è presa da AngularJs tutorial 14 - cercare "Animazioni fotogrammi chiave CSS: Animazione ngView", a circa metà della pagina.

Problemi correlati