2013-02-15 10 views
6

Ich baue eine kleine App und ich benutze AngularJS. Innerhalb der App brauche ich ein reduzierbares Element und die Verwendung von Twitter Bootstrap wäre so einfach wie das Hinzufügen der Bibliothek und einiger Tags auf meinem Zielelement und dem Auslöser.Etwas wie Bootstrap zusammenklappbar mit eckigen

Aber ich versuche nicht, andere externe Bibliotheken wie Bootstrap oder andere zu laden, so dass ich versuche, das gleiche Verhalten mit kantigem zu erreichen:

$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"); 
     }); 
    }; 

Wie Sie mich versuche, um den Übergang zu sehen die Höhe (da das Element einen Übergang auf der Höhe hat) und am Ende fügen Sie einfach die Klasse in hinzu. Aber das funktioniert nicht sehr gut, denn wenn ich am Übergangsende höre, wird es an jedem Übergangsende innerhalb dieses Elements ausgelöst.

Ich brauche Hilfe mit diesem, wie kann ich das Bootstrap zusammenklappbar nur mit eckigen schreiben? Ich brauche nicht die Ereignisse, die bootstrap hat wie auf shown, oder show, hide, ich muss nur eine einfache Kollaps des Elements mit Übergang auslösen und halten meine Elemente Höhe dynamisch (Ich möchte nicht eine feste Höhe, sonst Ich würde einfach CSS verwenden, um den Kollaps zu erreichen). Ich muss nur in die richtige Richtung geortet werden :)

Antwort

7

Scheint so, als wolltest du einfach etwas mit CSS3 Übergängen reduzieren?

Nun, Sie können das tun, aber der Controller ist der falsche Ort, um das zu tun. Sie sollten das mit Direktiven oder in einer benutzerdefinierten Direktive tun. Glücklicherweise können Sie dies mit den nativen Angular-Direktiven tun, z. B. ng-class.

HTML:

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

Und was am wichtigsten ist, Ihre 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.

Wichtig zu beachten, CSS3 Übergänge werden nicht in allen Browsern funktionieren. Besonders in IE. Am Ende wäre es wahrscheinlich besser, ein Plugin zu verwenden, das jemand anderes bereits erstellt hat, und es dann in einer benutzerdefinierten Direktive einzusetzen, die einen booleschen Wert anzeigt.

Ich hoffe, dass hilft.


EDIT

height: auto mit CSS Transitions nicht funktioniert (zumindest ab dem Zeitpunkt dieser Veröffentlichung). Aus diesem Grund möchten Sie wirklich das Plug-in von jemand anderem verwenden, anstatt das Rad neu zu erfinden. Auch wenn es nur die Methode animate() von JQuery ist. Der Pseudocode für die eigene Richtlinie rollen würde so etwas so sein: (vorausgesetzt, Sie verwenden 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); 
    } 
    } 
}); 

und dann würde es Ihnen gefällt verwenden:

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

Wieder Das obige ist psuedo-code, ich habe keine Ahnung, ob es funktioniert oder nicht, es ist nur, um Ihnen eine Idee zu folgen, wenn Sie wirklich wollen, um Ihre eigenen zu rollen.

+0

Wie ich in meiner Beschreibung erwähnt, 'collapsable.showMe {height: 100px; } ', sollte die Höhe' auto' sein, damit ich meine Inhaltshöhe dynamisieren kann, weil mehr Elemente nachträglich angehängt werden könnten ... – Roland

+0

Deshalb wirst du das Plugin von jemand anderem benutzen wollen. Was Sie tun müssen, ist die Höhe Ihres inneren Inhalts mit Javascript überprüfen und dann diese Höhe mit CSS im laufenden Betrieb einstellen. 'auto' funktioniert nicht mit CSS-Übergängen in irgendeinem Browser, den ich kenne. –

+0

War das nicht, was ich gerade in der Beschreibung gesagt habe? Die automatische Höhe würde in diesem Fall nicht funktionieren, wenn ich CSS-Übergänge möchte. Deshalb habe ich versucht, zuerst die Höhe zu setzen und dann die 'in'-Klasse hinzuzufügen, die' height: auto' hat. Nur die Verwendung am Ende des Übergangs funktioniert nicht. Die Höhe des Elements wird nicht funktionieren, da die Klasse 'collapse' es auf' 0px' setzt. Deshalb frage ich hier, ob es einen Weg gibt, es ohne die Ereignisse zu tun, die Bootstrap hat und nur den Kollaps hat. – Roland

1

Roland, werfen Sie einen Blick auf Bootstrap Project von Angular-UI-Team.

+0

Ich weiß es schon;) Das Akkordeon passt nicht zu meinen Bedürfnissen, ich muss es tun in der Lage sein, den Kollaps von irgendwo im Markup auszulösen. In diesem Fall hat das Bootstrap - Projekt eine Direktive, die das abdeckt, aber Sie können Ihren Trigger nicht außerhalb des Direktivenkontextes haben. – Roland

2

Wenn ich die Fragen verstehe, ist meine Lösung, Winkel $ animateCss zu verwenden. Hier sind die Dokumente und Beispiele https://docs.angularjs.org/api/ngAnimate/service/ $ animateCss

Mit $ animateCss-Service können Sie Ihre eigene Animation mit ngAnimate erstellen. Dies ist ein Beispiel für das Winkelmodul. Die Demo ist in dem unten stehenden Link

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

Während dieser Link die Frage beantworten kann, ist es besser, die wesentliche Teile der Antwort hier und bieten den Link als Referenz. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - [Aus Bewertung] (/ review/low-quality-posts/12532441) – DhiaTN

+0

Ich habe die Antwort mit einem Beispiel bearbeitet. – user3083618