Mam trasy ustawione w AngularJS w ten sposób:
$routeProvider
.when('/dashboard', {templateUrl:'partials/dashboard', controller:widgetsController})
.when('/lab', {templateUrl:'partials/lab', controller:widgetsController})
Mam kilka linków na górnym pasku w stylu zakładek. Jak mogę dodać „aktywną” klasę do zakładki w zależności od aktualnego szablonu lub adresu URL?
javascript
html
angularjs
Siergiej Baszarow
źródło
źródło
Odpowiedzi:
Sposobem rozwiązania tego problemu bez konieczności polegania na adresach URL jest dodanie atrybutu niestandardowego do każdej części podczas
$routeProvider
konfiguracji, na przykład:Odsłoń
$route
w kontrolerze:Ustaw
active
klasę w oparciu o aktualnie aktywną kartę:źródło
$scope.activeTab = $route.current.activetab
, aby kod HTML był trochę czystszy.$rootScope
sztuczką @ Lucasa poniżej, aby była dostępna we wszystkich zakresach.Jednym ze sposobów na to byłoby użycie dyrektywy ngClass i usługi $ location. W swoim szablonie możesz:
gdzie
isActive
byłaby funkcja w zakresie zdefiniowanym w ten sposób:Oto kompletny jsFiddle: http://jsfiddle.net/pkozlowski_opensource/KzAfG/
Powtarzanie
ng-class="{active:isActive('/dashboard')}"
na każdej karcie nawigacji może być żmudne (jeśli masz wiele kart), więc ta logika może być kandydatem do bardzo prostej dyrektywy.źródło
Zgodnie z radą Pawła, aby użyć niestandardowej dyrektywy, oto wersja, która nie wymaga dodawania ładunku do routeConfig, jest super deklaratywna i może być dostosowana do reagowania na dowolny poziom ścieżki, po prostu zmieniając, na którą
slice()
z nich zwracasz uwagę .Osiągamy nasze cele, nasłuchując
$routeChangeSuccess
wydarzenia, a nie umieszczając$watch
na ścieżce. Pracuję w przekonaniu, że to oznacza, że logika powinna działać rzadziej, ponieważ myślę, że patrzy na ogień w każdym$digest
cyklu.Wywołaj go, przekazując argument na poziomie ścieżki w deklaracji dyrektywy. Określa, do jakiego fragmentu bieżącej $ location.path () chcesz dopasować
href
atrybut.Tak więc, jeśli twoje karty powinny reagować na podstawowy poziom ścieżki, wprowadź argument „1”. Tak więc, gdy location.path () to „/ home”, będzie pasować do „# / home” w
href
. Jeśli masz zakładki, które powinny reagować na drugi poziom, trzeci lub jedenasty odcinek ścieżki, dostosuj odpowiednio. To odcięcie od 1 lub wyższego spowoduje pominięcie nikczemnego „#” w href, który będzie miał indeks 0.Jedynym wymaganiem jest wywołanie na
<a>
elemencie an , ponieważ element zakłada obecnośćhref
atrybutu, który będzie porównywać z bieżącą ścieżką. Jednak możesz dość łatwo dostosować się do odczytu / zapisu elementu nadrzędnego lub podrzędnego, jeśli wolisz wywołać<li>
coś takiego. Kopię to, ponieważ możesz go ponownie użyć w wielu kontekstach, po prostu zmieniając argument pathLevel. Jeśli w logice przyjęto głębokość odczytu, potrzebnych byłoby wiele wersji dyrektywy do użycia z wieloma częściami nawigacji.EDYCJA 18.03.14: Rozwiązanie nie zostało dostatecznie uogólnione i aktywowałoby się, gdyby zdefiniowano argument dla wartości „activeTab”, który zwraca
undefined
zarówno wartość „activeTab”, jak$location.path()
i wartość elementuhref
. Ponieważ:undefined === undefined
. Zaktualizowano, aby naprawić ten stan.Pracując nad tym, zdałem sobie sprawę, że powinna istnieć wersja, którą możesz po prostu zadeklarować w elemencie nadrzędnym, z taką strukturą szablonu:
Zauważ, że ta wersja nie przypomina już zdalnie kodu HTML w stylu Bootstrap. Ale jest bardziej nowoczesny i zawiera mniej elementów, więc mam słabość do tego. Ta wersja dyrektywy oraz oryginał są teraz dostępne na Github jako moduł, który można po prostu zadeklarować jako zależność. Byłbym szczęśliwy mogąc je Bower-ize, gdyby ktokolwiek faktycznie ich używał.
Ponadto, jeśli chcesz mieć wersję kompatybilną z bootstrapem, która zawiera ten
<li>
, możesz skorzystać z modułu Angular-ui-bootstrap Tabs , który, jak sądzę, pojawił się po tym oryginalnym poście i który jest być może nawet bardziej deklaratywny niż ten. Jest mniej zwięzły w przypadku podstawowych rzeczy, ale zapewnia dodatkowe opcje, takie jak wyłączone karty i deklaratywne zdarzenia, które uruchamiają się podczas aktywacji i dezaktywacji.źródło
ul
do elementów, a być może powinny być po prostu kolekcjami kotwic, owiniętymi przez jakiśnav
lub inny element grupujący. Radzenie sobie z warstwą pośredniczącąli
jest dodatkową złożonością bez żadnych korzyści, szczególnie teraz, gdy mamy donav
dyspozycji element, który pozwala wyjaśnić, co się dzieje.@ rob-juurlink Poprawiłem trochę twoje rozwiązanie:
zamiast każdej trasy wymagającej aktywnej karty; i potrzebując ustawić aktywną kartę w każdym kontrolerze, robię to:
A HTML wygląda tak. Activetab to tylko adres URL odnoszący się do tej trasy. To po prostu eliminuje potrzebę dodawania kodu do każdego kontrolera (przeciąganie zależności, takich jak $ route i $ rootScope, jeśli jest to jedyny powód ich użycia)
źródło
Może taka dyrektywa może rozwiązać Twój problem: http://jsfiddle.net/p3ZMR/4/
HTML
JS
źródło
Najprostsze rozwiązanie tutaj:
Jak ustawić aktywną klasę bootstrap navbar w Angular JS?
Który jest:
Użyj ng-controller, aby uruchomić pojedynczy kontroler poza ng-view:
i umieść w controllers.js:
źródło
Polecam korzystanie z modułu state.ui, który nie tylko obsługuje wiele i zagnieżdżonych widoków, ale także bardzo ułatwia tego rodzaju pracę (kod poniżej zacytowany):
Warte przeczytania.
źródło
Oto kolejna wersja zmiany LI XMLillies w / domi, która używa ciągu wyszukiwania zamiast poziomu ścieżki. Myślę, że jest to trochę bardziej oczywiste, co dzieje się w moim przypadku użycia.
HTML wygląda teraz następująco:
źródło
Uważam, że odpowiedź XMLilley jest najlepsza, najbardziej elastyczna i nieinwazyjna.
Jednak miałem małą usterkę.
Do użytku z nawigacją bootstrap, oto jak go zmodyfikowałem:
Dodałem „if (attrs.href! = Undefined)”, ponieważ ta funkcja jest wywoływana dwukrotnie, przy czym drugi raz powoduje błąd.
Co do html:
źródło
Przykład Bootstrap.
Jeśli używasz wbudowanego routingu Angulars (ngview), możesz użyć tej dyrektywy:
Zakładając, że Twój znacznik wygląda następująco:
Podoba mi się, że to robię, ponieważ możesz ustawić nazwę klasy, którą chcesz w swoim atrybucie.
źródło
Możesz także po prostu wstrzyknąć lokalizację do zakresu i użyć jej do odliczenia stylu nawigacji:
Następnie użyj go w
ng-class
:źródło
alternatywnym sposobem jest użycie ui-sref-active
Dyrektywa działająca wraz z ui-sref, która dodaje klasy do elementu, gdy stan powiązanej dyrektywy ui-sref jest aktywna, i usuwa je, gdy jest nieaktywna. Podstawowym przypadkiem użycia jest uproszczenie specjalnego wyglądu menu nawigacyjnych opartych na interfejsie ui-sref, ponieważ przycisk menu stanu „aktywnego” wygląda inaczej, odróżniając go od nieaktywnych elementów menu.
Stosowanie:
ui-sref-active = 'class1 class2 class3' - klasy "class1", "class2" i "class3" są dodawane do elementu dyrektywy, gdy powiązany stan ui-sref jest aktywny, i usuwane, gdy jest nieaktywny.
Przykład:
biorąc pod uwagę następujący szablon,
gdy stan aplikacji to „app.user” i zawiera parametr stanu „user” o wartości „bilbobaggins”, wynikowy kod HTML pojawi się jako
Nazwa klasy jest interpolowana jeden raz podczas łączenia dyrektyw (wszelkie dalsze zmiany wartości interpolowanej są ignorowane). Wiele klas można określić w formacie oddzielonym spacjami.
Użyj dyrektywy ui-sref-opts, aby przekazać opcje do $ state.go (). Przykład:
źródło
Zgadzam się z postem Roba dotyczącym posiadania niestandardowego atrybutu w kontrolerze. Najwyraźniej nie mam wystarczającej liczby przedstawicieli, aby komentować. Oto żądany plik jsfiddle:
przykładowy html
przykładowy plik app.js
http://jsfiddle.net/HrdR6/
źródło
I użyj poniższego szablonu:
źródło
Potrzebowałem rozwiązania, które nie wymaga zmian w kontrolerach, ponieważ dla niektórych stron renderujemy tylko szablony i w ogóle nie ma kontrolera. Dzięki wcześniejszym komentatorom, którzy zasugerowali skorzystanie
$routeChangeSuccess
, wymyśliłem coś takiego:Nie zależy od adresów URL, dzięki czemu jest naprawdę łatwy do skonfigurowania dla dowolnych podstron itp.
źródło
Nie pamiętam, gdzie znalazłem tę metodę, ale jest dość prosta i działa dobrze.
HTML:
CSS:
źródło
Jeśli używasz ngRoute (do routingu), Twoja aplikacja będzie miała poniższą konfigurację,
Teraz wystarczy dodać kontroler w tej konfiguracji, tak jak poniżej,
Jak wspomniałeś o aktywnej karcie w swojej konfiguracji, teraz wystarczy dodać aktywną klasę do swojego tagu
<li>
lub<a>
. Lubić,Oznacza to, że za każdym razem, gdy użytkownik kliknie stronę o stronie, automatycznie zidentyfikuje bieżącą kartę i zastosuje aktywną klasę css.
Mam nadzieję, że to pomoże!
źródło
Przyszedłem tutaj po rozwiązanie ... chociaż powyższe rozwiązania działają dobrze, ale okazało się, że są trochę skomplikowane, niepotrzebne. Dla osób, które wciąż szukają łatwego i zgrabnego rozwiązania, doskonale wykona zadanie.
źródło