AngularJS Tutorial Series: Teil 3 – So erstellen Sie ein Schiebemenü mit Direktiven

Dieses AngularJS-Mini-Tutorial für Fortgeschrittene ist Teil 3 einer 5-teiligen Serie, in der Sie jeweils lernen, wie Sie etwas erstellen, das Sie auf Ihrer Webseite verwenden können. In diesem Tutorial erfahren Sie, wie Sie unter anderem mit AngularJS-Direktiven ein Schiebemenü erstellen.

Andere Beiträge in der Serie:

Ich möchte darüber sprechen, wie man ein Schiebemenü-Steuerelement mit erstellt Winkel JS und WENIGER CSS. Die Grundidee ist, dass ich möchte, dass ein Menü basierend auf einer externen Controller-Aktion entweder von der linken oder der rechten Seite des Bildschirms eingeblendet wird.

Angularjs Schiebemenü

Wenn Sie die Art von Person sind, die das Gesamtbild sehen möchte, anstatt sich ein Schritt-für-Schritt-Tutorial für Sie auszulegen, habe ich eine Demoseite zusammengestellt, die Sie sehen können hier. Das Menü selbst wird eine Angular JS-Direktive sein, die nur zwei Argumente akzeptiert: sichtbar und Ausrichtung. Visible gibt an, welche Controller-Variable für die Anzeige des Menüs verantwortlich sein soll, und die Ausrichtungsvariable bestimmt, ob das Menü von der linken Seite des Bildschirms oder von der rechten Seite des Bildschirms eingeblendet wird oder nicht.

Dieser Artikel wird in drei separate Abschnitte unterteilt: HTML, JavaScript und CSS. Der HTML-Code zeigt, wie ich die Menüdirektive aufgebaut habe, und bietet auch Beispiele für die Verwendung. Das JavaScript ist das Herzstück des Artikels und erklärt, wie die Sliding Menu-Direktive erstellt wird und wie der Angular JS-Controller in die Direktive selbst eingebunden wird. Das CSS ist etwas kompliziert, da ich schicke Animationen hinzufüge, um das eigentliche Gleiten zu machen, aber abgesehen davon ist es einfach nur ein alter Stil.

HTML

Beispielnutzung

Verwenden Sie Folgendes, um die Sliding Menu-Direktive zu Ihrer Seite hinzuzufügen, wobei „visible“ und „alignment“ Variablen auf Ihrem Controller sind.

<menu visible="visible" alignment="left">
    <menu-item hash="first-page">First Page></menu-item>
    <menu-item hash="second-page">Second Page></menu-item>
    <menu-item hash="third-page">Third Page></menu-item>
</menu>

Richtlinie

Hier ist der HTML-Code für die Richtlinienvorlage. Es ist relativ einfach, aber ich würde trotzdem empfehlen, dass Sie dies zur einfacheren Verwendung in einer separaten Datei ablegen. Das einzig Interessante, was hier vor sich geht, ist die Verwendung von der Klasse Direktive, die angibt, dass dem angegebenen Element basierend auf der Richtigkeit der angegebenen Variablen eine CSS-Klasse hinzugefügt wird. Wenn in diesem Fall „sichtbar“ wahr ist (d. h. nicht null oder undefiniert), wird die Klasse „show“ zum übergeordneten div hinzugefügt. Auch hier setze ich die Ausrichtungsklasse, wobei left die linke Klasse und right die rechte zuweisen. Das von transklusion Direktive wird verwendet, um untergeordnete Elemente in die Direktive zu rendern. Das obige Verwendungsbeispiel bezeichnet beispielsweise drei Menüelemente; diese drei Knoten würden innerhalb des gerenderten HTML für das Menü platziert werden, wie unten beschrieben.

<div ng-class="{ show: visible, left: alignment === \"left\", right: alignment === \"right\" }" ng-transclude></div>

JavaScript

Das JavaScript ist in verschiedene Abschnitte unterteilt. Zuerst gibt es die Initialisierung der Angular JS-Anwendung. Zweitens werfen wir einen Blick auf den Controller, der die Direktive initialisiert. Und schließlich werfen wir einen Blick auf die beiden Direktiven, die zum Rendern des Menüs verwendet werden: das Menü selbst und die verschachtelten Menüelemente.

Anwendung

Hier initialisieren wir die Angular JS-Anwendung und verbinden dann einige Ereignisse, mit denen wir die Menüs ausblenden können, sobald sie angezeigt werden. Wenn der Benutzer die Escape-Taste drückt oder irgendwo auf das Dokument klickt, sollten die Menüs ausgeblendet werden. Angular JS hat Event-Emitter in seine Scope-Objekte eingebaut, also verwenden wir diese auf der $rootScope -Variable, bei der es sich um den übergreifenden Bereich handelt, der letztendlich allen anderen Bereichen in Ihrer Anwendung übergeordnet ist.

Notiz: Sie müssen die Weitergabe des Ereignisses stoppen, das zum Auslösen der Anzeige der Menüs verwendet wird, denn wenn Sie dies nicht tun, blendet dieser dokumentweite Click-Handler das Menü sofort aus, nachdem es angezeigt wurde. Werfen Sie einen Blick auf die Testseite für ein Beispiel, wie man das macht.

var app = angular.module("demo", []);

app.run(function($rootScope) {
    document.addEventListener("keyup", function(e) {
        if (e.keyCode === 27)
            $rootScope.$broadcast("escapePressed", e.target);
    });

    document.addEventListener("click", function(e) {
        $rootScope.$broadcast("documentClicked", e.target);
    });
});

Regler

Hier ist ein Beispiel dafür, wie Ihr Controller die Menüs manipulieren würde, um sie anzuzeigen und auszublenden. Die Funktionen showLeft und showRight würden das linke bzw. rechte Menü anzeigen, und wir binden den oben erwähnten Event-Emitter auf dem ein $rootScope variabel über die $on Methoden, um die Menüs gegebenenfalls zu schließen.

app.controller("modalDemo", function($scope, $rootScope) {
    $scope.leftVisible = false;
    $scope.rightVisible = false;

    $scope.close = function() {
        $scope.leftVisible = false;
        $scope.rightVisible = false;
    };

    $scope.showLeft = function(e) {
        $scope.leftVisible = true;
        e.stopPropagation();
    };

    $scope.showRight = function(e) {
        $scope.rightVisible = true;
        e.stopPropagation();
    }

    $rootScope.$on("documentClicked", _close);
    $rootScope.$on("escapePressed", _close);

    function _close() {
        $scope.$apply(function() {
            $scope.close(); 
        });
    }
});

Richtlinien

Hier ist der Code, um die beiden Anweisungen im Menü zu steuern. Beide sind auf Elemente beschränkt (über die restrict: "E" Option), und wir transkludieren den inneren Inhalt beider in den Inhalt jeder Direktive. Das bedeutet, dass der innere Inhalt der menu-Direktive im obigen Beispiel in das unmittelbar untergeordnete div des Menüs geschrieben wird. Der innere Inhalt jedes Menüelement-Tags (nämlich der Text, den wir in den Menüelementen anzeigen möchten) wird auch in jedem Menüelement gerendert. Angular JS weiß, wo die transkludierten Inhalte über die abgelegt werden sollen von transklusion Direktive, die Sie in beiden Vorlagen unten sehen. Für die menu-Direktive haben wir einen isolierten Gültigkeitsbereich erstellt, der die sichtbare bidirektionale Bindung und die unidirektionale Ausrichtungsbindung enthält. Dadurch können wir den Wert der sichtbaren Variablen und den Zeichenfolgenwert der Ausrichtung lesen. Ähnlich verfahren wir mit der Hash-Variablen im isolierten Geltungsbereich des Menüeintrags. Schließlich hat der Menüeintrag eine Methode, die über die Funktion der Link-Option, navigation, zu seinem Gültigkeitsbereich hinzugefügt wurde, die ausgelöst wird, wenn der Benutzer auf den Menüeintrag klickt, wie in zu sehen ist von Klicks Richtlinie.

app.directive("menu", function() {
    return {
        restrict: "E",
        template: "<div ng-class="{ show: visible, left: alignment === \"left\", right: alignment === \"right\" }" ng-transclude></div>",
        transclude: true,
        scope: {
            visible: "=",
            alignment: "@"
        }
    };
});

app.directive("menuItem", function() {
     return {
         restrict: "E",
         template: "<div ng-click='navigate()' ng-transclude></div>",
         transclude: true,
         scope: {
             hash: "@"
         },
         link: function($scope) {
             $scope.navigate = function() {
                 window.location.hash = $scope.hash;
             }
         }
     }
});

CSS

Schließlich ist hier das CSS. Die ersten drei Zeilen beschreiben einige LESS-CSS-Mixins, die ich definiert habe, um den Anbieterpräfix-Albtraum zu erleichtern. Die erste dient zum Definieren von Übergängen (oder Animationen); die zweite ist für CSS-Transformationen; und der dritte besteht darin, den Rahmenwert für die Boxgröße festzulegen. Darunter befindet sich das CSS für das Menü und darin jedes Menüelement. Ich mache großzügigen Gebrauch davon & LESS CSS-Befehl, mit dem ich Stile für verschiedene Bedingungen angeben kann, die in diesem Fall zusätzliche Klassen sind, wie left, show usw. Diese werden fast ausschließlich verwendet, um die Positionierung der Menüs abhängig von der angegebenen Ausrichtung zu definieren.

.transition (@value1,@value2:X,...) { @value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`; -webkit-transition: @value; -moz-transition: @value; -ms-transition: @value; -o-transition: @value; transition: @value; }
.transform (@value1,@value2:X,...) { @value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`; transform:@value; -ms-transform:@value; -webkit-transform:@value; -o-transform:@value; -moz-transform:@value; }
.border-box { box-sizing:border-box; -moz-box-sizing:border-box; }

menu { display:block;
    @menu-width:250px;
    >div { position:absolute; z-index:2; top:0;  width:@menu-width; height:100%; .border-box; .transition(-webkit-transform ease 250ms); .transition(transform ease 250ms);
        &.left { background:#273D7A; left:@menu-width*-1; }
        &.show.left { .transform(translate3d(@menu-width, 0, 0)); }

        &.right { background:#6B1919; right:@menu-width*-1; }
        &.show.right { .transform(translate3d(@menu-width*-1, 0, 0)); }

        >menu-item { display:block;
            >div { float:left; width:100%; margin:0; padding:10px 15px; border-bottom:solid 1px #555; cursor:pointer; .border-box; color:#B0B0B0;
                &:hover { color:#F0F0F0; }
                >span { float:left; color:inherit; }
            }
        }
    }
}

Fazit

Das ist es! Ich hoffe, das hat Sie beim Lesen etwas gelehrt. Wenn Sie diese Menüs in Aktion sehen möchten, können Sie sich das ansehen Demoseite, wodurch der Seite sowohl ein linkes als auch ein rechtes Menü hinzugefügt wird. Danke fürs Lesen!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *