Ich habe Routen in AngularJS wie folgt eingestellt:
$routeProvider
.when('/dashboard', {templateUrl:'partials/dashboard', controller:widgetsController})
.when('/lab', {templateUrl:'partials/lab', controller:widgetsController})
Ich habe einige Links in der oberen Leiste, die als Registerkarten gestaltet sind. Wie kann ich einer Registerkarte abhängig von der aktuellen Vorlage oder URL eine aktive Klasse hinzufügen?
javascript
html
angularjs
Sergei Basharov
quelle
quelle
Antworten:
Eine Möglichkeit, dies zu lösen, ohne sich auf URLs verlassen zu müssen, besteht darin, jedem Teil während der
$routeProvider
Konfiguration ein benutzerdefiniertes Attribut hinzuzufügen , wie folgt :Belichten Sie
$route
in Ihrem Controller:Legen Sie die
active
Klasse basierend auf der aktuell aktiven Registerkarte fest:quelle
$scope.activeTab = $route.current.activetab
damit Sie das HTML ein wenig sauberer halten können.$rootScope
Trick von @ Lucas , um ihn in allen Bereichen verfügbar zu machen.Eine Möglichkeit hierfür wäre die Verwendung der ngClass-Direktive und des $ location-Dienstes. In Ihrer Vorlage können Sie Folgendes tun:
Wo
isActive
wäre eine Funktion in einem so definierten Bereich:Hier ist die komplette jsFiddle: http://jsfiddle.net/pkozlowski_opensource/KzAfG/
Das Wiederholen
ng-class="{active:isActive('/dashboard')}"
auf jeder Navigationsregisterkarte kann mühsam sein (wenn Sie viele Registerkarten haben), daher ist diese Logik möglicherweise ein Kandidat für eine sehr einfache Anweisung.quelle
Befolgen Sie die Empfehlungen von Pavel, eine benutzerdefinierte Direktive zu verwenden. Hier ist eine Version, bei der der routeConfig keine Nutzdaten hinzugefügt werden müssen. Sie ist sehr deklarativ und kann an jede Ebene des Pfads angepasst werden, indem Sie einfach ändern, auf welche
slice()
davon Sie achten .Wir erreichen unsere Ziele, indem wir auf das
$routeChangeSuccess
Ereignis hören, anstatt ein$watch
auf den Weg zu bringen. Ich arbeite unter der Überzeugung, dass dies bedeutet, dass die Logik weniger häufig ausgeführt werden sollte, da ich denke, dass Uhren bei jedem$digest
Zyklus feuern .Rufen Sie es auf, indem Sie Ihr Argument auf Pfadebene für die Direktivendeklaration übergeben. Dies gibt an, mit welchem Teil des aktuellen $ location.path () Sie Ihr
href
Attribut abgleichen möchten .Wenn Ihre Registerkarten auf die Basisebene des Pfads reagieren sollen, geben Sie das Argument '1' ein. Wenn location.path () "/ home" ist, stimmt es mit dem "# / home" in der
href
. Wenn Sie Registerkarten haben, die auf die zweite oder dritte oder elfte Ebene des Pfads reagieren sollen, passen Sie sie entsprechend an. Dieses Schneiden von 1 oder höher umgeht das schändliche '#' in der href, das bei Index 0 leben wird.Die einzige Voraussetzung ist, dass Sie ein aufrufen
<a>
, da das Element das Vorhandensein eineshref
Attributs voraussetzt , das mit dem aktuellen Pfad verglichen wird. Sie können sich jedoch relativ leicht anpassen, um ein übergeordnetes oder untergeordnetes Element zu lesen / schreiben, wenn Sie das<li>
oder etwas aufrufen möchten. Ich grabe dies, weil Sie es in vielen Kontexten wiederverwenden können, indem Sie einfach das Argument pathLevel variieren. Wenn die zu lesende Tiefe in der Logik angenommen wurde, benötigen Sie mehrere Versionen der Direktive, um sie mit mehreren Teilen der Navigation zu verwenden.EDIT 18.03.14: Die Lösung wurde nicht ausreichend verallgemeinert und wird aktiviert, wenn Sie ein Argument für den Wert von 'activeTab' definieren, das
undefined
sowohl für beide$location.path()
als auch für das Element zurückgegeben wirdhref
. Weil :undefined === undefined
. Aktualisiert, um diesen Zustand zu beheben.Während ich daran arbeitete, wurde mir klar, dass es eine Version geben sollte, die Sie einfach für ein übergeordnetes Element deklarieren können, mit einer Vorlagenstruktur wie dieser:
Beachten Sie, dass diese Version nicht mehr im entferntesten Stil HTML im Bootstrap-Stil ähnelt. Aber es ist moderner und verwendet weniger Elemente, also bin ich parteiisch. Diese Version der Direktive sowie das Original sind jetzt auf Github als Drop-In-Modul verfügbar, das Sie einfach als Abhängigkeit deklarieren können. Ich würde sie gerne bower-ize, wenn jemand sie tatsächlich benutzt.
Wenn Sie eine Bootstrap-kompatible Version wünschen, die
<li>
's' enthält , können Sie auch das Angular-UI-Bootstrap-Tabs-Modul verwenden , das meiner Meinung nach nach diesem ursprünglichen Beitrag herausgekommen ist und das vielleicht sogar noch aussagekräftiger ist als dieses. Es ist weniger prägnant für grundlegende Dinge, bietet Ihnen jedoch einige zusätzliche Optionen, wie deaktivierte Registerkarten und deklarative Ereignisse, die beim Aktivieren und Deaktivieren ausgelöst werden.quelle
ul
und vielleicht nur Sammlungen von Ankern sein sollten, die von einemnav
oder einem anderen Gruppierungselement umhüllt sind . Der Umgang mit der Zwischenschicht vonli
's ist eine zusätzliche Komplexität ohne Auszahlung, insbesondere jetzt, wo wir dasnav
Element zur Verfügung haben, um klar zu machen, was los ist.@ rob-juurlink Ich habe deine Lösung ein bisschen verbessert:
anstelle jeder Route, die eine aktive Registerkarte benötigt; und ich muss die aktive Registerkarte in jedem Controller einstellen, um Folgendes zu tun:
Und das HTML sieht so aus. Das Activetab ist nur die URL, die sich auf diese Route bezieht. Dadurch entfällt lediglich die Notwendigkeit, Code in jedem Controller hinzuzufügen (Ziehen von Abhängigkeiten wie $ route und $ rootScope, wenn dies der einzige Grund ist, warum sie verwendet werden).
quelle
Vielleicht könnte eine solche Anweisung Ihr Problem lösen: http://jsfiddle.net/p3ZMR/4/
HTML
JS
quelle
Einfachste Lösung hier:
Wie setze ich die aktive Bootstrap Navbar-Klasse mit Angular JS?
Welches ist:
Verwenden Sie ng-controller, um einen einzelnen Controller außerhalb der ng-Ansicht auszuführen:
und in controller.js aufnehmen:
quelle
Ich empfehle die Verwendung des state.ui-Moduls, das nicht nur mehrere und verschachtelte Ansichten unterstützt, sondern auch diese Art der Arbeit sehr einfach macht (Code unten zitiert):
Lesenswert.
quelle
Hier ist eine weitere Version der LI-Änderung von XMLillies mit domi, bei der anstelle einer Pfadebene eine Suchzeichenfolge verwendet wird. Ich denke, das ist etwas offensichtlicher, was für meinen Anwendungsfall passiert.
HTML sieht jetzt so aus:
quelle
Ich fand XMLilleys Antwort die beste und anpassungsfähigste und nicht aufdringlichste.
Ich hatte jedoch eine kleine Panne.
Für die Verwendung mit Bootstrap Nav habe ich Folgendes geändert:
Ich habe "if (attrs.href! = Undefined)" hinzugefügt, da diese Funktion anscheinend zweimal aufgerufen wird und das zweite Mal einen Fehler erzeugt.
Wie für das HTML:
quelle
Bootstrap-Beispiel.
Wenn Sie Angulars verwenden, die im Routing (ngview) integriert sind, kann diese Anweisung verwendet werden:
Angenommen, Ihr Markup sieht folgendermaßen aus:
Ich mag es, dies zu tun, da Sie den gewünschten Klassennamen in Ihrem Attribut festlegen können.
quelle
Sie können den Ort auch einfach in den Bereich einfügen und daraus den Stil für die Navigation ableiten:
Dann verwenden Sie es in Ihrem
ng-class
:quelle
Eine alternative Möglichkeit ist die Verwendung von ui-sref-active
Eine Direktive, die mit ui-sref zusammenarbeitet, um einem Element Klassen hinzuzufügen, wenn der Status der zugehörigen ui-sref-Direktive aktiv ist, und diese zu entfernen, wenn sie inaktiv ist. Der Hauptanwendungsfall besteht darin, das spezielle Erscheinungsbild von Navigationsmenüs zu vereinfachen, die auf ui-sref basieren, indem die Menüschaltfläche des Status "aktiv" anders angezeigt wird und sich von den inaktiven Menüelementen unterscheidet.
Verwendung:
ui-sref-active = 'class1 class2 class3' - Die Klassen "class1", "class2" und "class3" werden jeweils zum Direktivenelement hinzugefügt, wenn der Status des zugehörigen ui-sref aktiv ist, und entfernt, wenn er inaktiv ist.
Beispiel:
Angesichts der folgenden Vorlage:
Wenn der App-Status "app.user" ist und den Statusparameter "user" mit dem Wert "bilbobaggins" enthält, wird der resultierende HTML-Code als angezeigt
Der Klassenname wird während der Verknüpfungszeit der Direktiven einmal interpoliert (weitere Änderungen am interpolierten Wert werden ignoriert). Es können mehrere Klassen in einem durch Leerzeichen getrennten Format angegeben werden.
Verwenden Sie die Direktive ui-sref-opts, um Optionen an $ state.go () zu übergeben. Beispiel:
quelle
Ich stimme Robs Beitrag über ein benutzerdefiniertes Attribut im Controller zu. Anscheinend habe ich nicht genug Repräsentanten, um einen Kommentar abzugeben. Hier ist die angeforderte jsfiddle:
Beispiel HTML
Beispiel app.js.
http://jsfiddle.net/HrdR6/
quelle
Und verwenden Sie das Folgende in der Vorlage:
quelle
Ich brauchte eine Lösung, die keine Änderungen an den Controllern erfordert, da für einige Seiten nur Vorlagen gerendert werden und es überhaupt keinen Controller gibt. Dank früherer Kommentatoren, die vorgeschlagen haben, habe
$routeChangeSuccess
ich mir so etwas ausgedacht:Es hängt nicht von URLs ab und ist daher sehr einfach, es für Unterseiten usw. einzurichten.
quelle
Ich kann mich nicht erinnern, wo ich diese Methode gefunden habe, aber sie ist ziemlich einfach und funktioniert gut.
HTML:
CSS:
quelle
Wenn Sie ngRoute (für das Routing) verwenden, hat Ihre Anwendung die folgende Konfiguration:
Fügen Sie jetzt einfach einen Controller in dieser Konfiguration hinzu, wie unten beschrieben.
Wie Sie in Ihrer Konfiguration die Registerkarte "Aktiv" erwähnt haben, müssen Sie jetzt nur noch eine aktive Klasse in Ihr
<li>
oder<a>
-Tag einfügen. Mögen,Das heißt, wenn der Benutzer auf eine Info-Seite klickt, wird automatisch die aktuelle Registerkarte identifiziert und die aktive CSS-Klasse angewendet.
Ich hoffe das hilft!
quelle
Kam hier für die Lösung .. obwohl oben Lösungen funktionieren gut, aber fanden sie ein wenig komplex unnötig. Für Leute, die immer noch nach einer einfachen und ordentlichen Lösung suchen, wird es die Aufgabe perfekt erledigen.
quelle