2013-02-15 18 views
6

Sto costruendo una piccola app e sto usando AngularJS. All'interno dell'app ho bisogno di un elemento pieghevole e usare Twitter Bootstrap sarebbe facile come aggiungere la libreria e alcuni tag sul mio elemento di destinazione e il trigger.Qualcosa come Bootstrap pieghevole con angolare

Ma sto cercando di non caricare altre librerie esterne come bootstrap o di qualsiasi altro, così mi è stato cercando di raggiungere lo stesso comportamento con angolare:

$scope.collapse = function(target) { 

     var that = angular.element(document).find(target), 

      transitioned = { 
       'WebkitTransition' : 'webkitTransitionEnd', 
       'MozTransition' : 'transitionend', 
       'OTransition'  : 'oTransitionEnd otransitionend', 
       'msTransition'  : 'MSTransitionEnd', 
       'transition'  : 'transitionend' 
      }, 

      _transitioned = transitioned[ Modernizr.prefixed('transition') ], 

      height = that.outerHeight(true); 

     if (angular.element(that).hasClass("in")) { 
      that.height(0); 
     } else { 
      that.height(height); 
     }; 

     that.on(_transitioned, function() { 
      that.toggleClass("in"); 
     }); 
    }; 

Come si può vedere che sto cercando di transizione l'altezza (dato che l'elemento ha una transizione sull'altezza) e alla fine basta aggiungere la classe in. Ma non sta funzionando molto bene, perché se sto ascoltando la transizione, si innescherà su qualsiasi estremità di transizione all'interno di quell'elemento.

Avrei bisogno di aiuto con questo, come posso riscrivere il bootstrap comprimibile solo con angolare? Non ho bisogno degli eventi che ha il bootstrap su shown, hidden o show, hide, ho solo bisogno di innescare un semplice collasso dell'elemento con transizione e mantenere i miei elementi di altezza dinamica (non voglio un'altezza fissa, altrimenti Vorrei solo usare i CSS per ottenere il collasso). Devo solo essere individuato nella giusta direzione :)

risposta

7

Sembra che tu voglia semplicemente comprimere qualcosa con transizioni CSS3?

Bene, puoi farlo, ma il controller è il posto sbagliato per farlo. Dovresti farlo con le direttive o in una direttiva personalizzata. Fortunatamente, puoi farlo con le direttive native Angular, come ng-class.

HTML:

<button ng-click="open = !open">Toggle</button>  
<div ng-class="{ showMe: open }" class="collapsable"> 
    <h3>This should collapse</h3> 
</div> 

E, soprattutto, il vostro CSS:

.collapsable { 
    display: inline-block; 
    overflow: hidden; 
    height: 0; 
    transition: height 1s; 
    -webkit-transition: height 1s;   
    -moz-transition: height 1s;   
    -o-transition: height 1s;   
    } 
    .collapsable.showMe { 
    height: 100px; 
    } 

And here is a plunker of it working.

importante notare, le transizioni CSS3 non funziona in tutti i browser. In particolare in IE. Alla fine, penso che probabilmente starai meglio usando un plug-in che qualcun altro ha già realizzato, e quindi sfruttandolo in una direttiva personalizzata che ha osservato alcuni valori booleani.

Spero che questo aiuti.


EDIT

height: auto non funziona con transizioni CSS (almeno a partire dal momento di questo post). Quindi, questo è il motivo per cui vorrai davvero utilizzare il plugin di qualcun altro, piuttosto che reinventare la ruota. Anche se è solo il metodo animate() di JQuery. La pseudo-codice per posizionare il proprio direttiva sarebbe qualcosa di simile in modo da: (presumendo che si sta utilizzando JQuery)

app.directive('collapseWhen', function() { 
    return function(scope, elem, attr) { 
    scope.$watch(attr.collapseWhen, function(val) { 
     var clone = elem.clone().appendTo('body'); 
     var h = clone.height(); 
     clone.remove(); 
     scope.animate({ height: (val ? h : 0) + 'px' }, 1000); 
    } 
    } 
}); 

e quindi devi usare le cose come:

<button ng-click="foo = !foo">Toggle</button> 
<div collapse-when="foo"> 

Anche in questo caso, quanto sopra è psuedo-code, non ho idea se funzionerà o no, è solo per darvi un'idea da seguire se si davvero vuole rotolare il proprio.

+0

Come ho detto nella mia descrizione, 'collapsable.showMe {height: 100px; } ', l'altezza dovrebbe essere' auto', quindi posso avere il mio altezza del contenuto dinamico, perché più elementi possono essere aggiunti afterwords ... – Roland

+0

Ecco perché vorrete usare il plugin di qualcun altro. Quello che devi fare è controllare l'altezza del tuo contenuto interno con javascript, e quindi impostare quella altezza con CSS al volo. 'auto' non funziona con le transizioni CSS in qualsiasi browser che conosco. –

+0

Non era quello che ho appena detto nella descrizione? Che avere altezza automatica non funzionerebbe in questo caso quando voglio le transizioni css. Ecco perché stavo cercando di impostare prima l'altezza e poi aggiungere la classe 'in' che ha' height: auto'. Solo che l'utilizzo della transizione non funzionerà. Né ottenere l'altezza dell'elemento funzionerà dal momento che la classe 'collapse' imposta su' 0px'. Ecco perché sto chiedendo qui se c'è un modo per farlo senza gli eventi che ha il bootstrap e hanno solo il collasso. – Roland

1

Roland, dai uno sguardo allo Bootstrap Project dal team angular-ui.

+0

Lo so già;) La fisarmonica non si adatta alle mie esigenze, devo essere in grado di attivare il collasso da qualsiasi punto del markup, nel qual caso il progetto bootstrap ha una direttiva che lo copre ma non è possibile avere il trigger esterno al contesto della direttiva – Roland

2

Se ho capito le domande, la mia soluzione è usare angular $ animateCss. Qui ci sono i documenti e gli esempi https://docs.angularjs.org/api/ngAnimate/service/ $ animateCss

Con il servizio $ animateCss puoi creare la tua animazione utilizzando ngAnimate. Questo è un esempio del modulo angolare. La demo è nel link qui sotto

var AppModule = angular.module('myApp', ['ngAnimate']) 
    .controller('collapseCtrl', ['$scope', function($scope) { 
    $scope.btn1 = $scope.btn2 = $scope.btn3 = false; 
    }]).animation('.my-collapse', ['$animateCss', function($animateCss) { 
    return { 
     enter: function(element, doneFn) { 
     var height = element[0].offsetHeight; 
     return $animateCss(element, { 
      from: { 
      height: '0px', 
      overflow: 'hidden' 
      }, 
      to: { 
      height: height + 'px' 
      }, 
      cleanupStyles: true, 
      duration: 0.3 // one second 
     }); 
     }, 
     leave: function(element, doneFn) { 
     var height = element[0].offsetHeight; 
     return $animateCss(element, { 
      to: { 
      height: '0px', 
      overflow: 'hidden' 
      }, 
      from: { 
      height: height + 'px' 
      }, 
      cleanupStyles: true, 
      duration: 0.3 // one second 
     }); 
     } 
    }; 
    }]); 

https://plnkr.co/edit/DjU1A2vmiBB1dYXjkiN1

+0

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere il parti essenziali della risposta qui e fornire il collegamento per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - [Dalla recensione] (/ recensione/post di bassa qualità/12532441) – DhiaTN

+0

Ho modificato la risposta con un esempio. – user3083618

Problemi correlati