dodawanie i usuwanie klas w angularJs za pomocą ng-click

97

Próbuję pracować, jak dodać klasę za pomocą ngClick. Wgrałem swój kod na plunker Kliknij tutaj . Patrząc na dokumentację kątową, nie mogę dowiedzieć się, jak należy to zrobić. Poniżej znajduje się fragment mojego kodu. Czy ktoś może poprowadzić mnie we właściwym kierunku

 <div ng-show="isVisible" ng-class="{'selected': $index==selectedIndex}" class="block"></div>

Kontroler

var app = angular.module("MyApp", []);
app.controller("subNavController", function ($scope){

        $scope.toggle = function (){
            $scope.isVisible = ! $scope.isVisible;
        };

        $scope.isVisible = false;
    });
NewKidOnTheBlock
źródło
z demonstracji lub wyjaśnienia nie wynika jasno, jaki jest cel. Wygląda na to, że próbujesz przełączyć menu, ale dlaczego przełączasz tylko łącze menu w wersji demonstracyjnej?
charlietfl

Odpowiedzi:

110

Wystarczy powiązać zmienną z dyrektywą „ng-class” i zmienić ją w kontrolerze. Oto przykład, jak to zrobić:

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

app.controller("con",function($scope){
  $scope.class = "red";
  $scope.changeClass = function(){
    if ($scope.class === "red")
      $scope.class = "blue";
    else
      $scope.class = "red";
  };
});
.red{
  color:red;
}

.blue{
  color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="ap" ng-controller="con">
  <div ng-class="class">{{class}}</div>
  <button ng-click="changeClass()">Change Class</button>    
</body>

Oto przykład pracy na jsFiddle

geonunez
źródło
29
classjest słowem zastrzeżonym, użyj classNamezamiast niego, kompilator YUI nie uda się go zminifikować.
Orlando
7
A co jeśli chcę użyć tego kodu dla więcej niż jednego elementu div w tym samym widoku? ten kod faktycznie zmień klasę dla wszystkich div, jak mogę zastosować klasę tylko do zaznaczonego elementu klikniętego
xzegga
Dzięki. Aby w pełni zrozumieć, co dzieje się po kliknięciu przycisku Zmień klasę, otwórz konsolę i wyświetl kod.
fidev
1
Spójrz również na ten wątek SO. Może nie być w 100% powiązany z zakresem pytania, ale nadal zawiera dodatkowe przydatne informacje: stackoverflow.com/questions/31047094/…
BiLaL
144

Chcę dodać lub usunąćactive” klasę w moim kodu dynamicznie na ng-clicktu co mam zrobić.

<ul ng-init="selectedTab = 'users'">
   <li ng-class="{'active':selectedTab === 'users'}" ng-click="selectedTab = 'users'"><a href="#users" >Users</a></li>
   <li ng-class="{'active':selectedTab === 'items'}" ng-click="selectedTab = 'items'"><a href="#items" >Items</a></li>
</ul>
cutedevil086
źródło
13
-1 dla ng-init. Według dokumentów AngularJS -The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Mike Grabowski,
2
Po prostu unikam części kontrolera "tutaj", ponieważ jest to tylko po to, aby pokazać podstawową funkcjonalność, jak to zrobić ...
cutedevil086
1
Możesz także użyć nieudokumentowanej składni `ng-class =" {'active': true} [selectedTab === 'users'] "`
Cody
Nie rozumiem, dlaczego to zadziała. Robię coś bardzo podobnego w Angular 1.3.8 i klasa warunkowa nie jest usuwana z elementu po kliknięciu innego. Zakładałbym, ponieważ inne elementy nie są ponownie renderowane. Dlaczego więc to kiedykolwiek zadziałało? Czy stare wersje Angulara odbudowały całą listę po kliknięciu pojedynczego elementu?
Matt Molnar,
Dodam to, ponieważ może to pomóc komuś innemu. angular-ui-router ma funkcje, które określasz i wiele więcej. Tworzysz stany, które są reprezentowane przez uri. Każdy stan może mieć 1 lub więcej kontrolerów, 1 lub więcej szablonów i 1 lub więcej powiązanych z nimi widoków. Linki są generowane przy użyciu dyrektywy ui-sref. Dyrektywa ui-sref-active wiąże określoną klasę z tym elementem, gdy stan jest aktywny. Dokumentacja Angular UI-Router
deadbabykitten
12

Można to zrobić w prosty i przejrzysty sposób za pomocą samych dyrektyw.

<div ng-class="{'class-name': clicked}" ng-click="clicked = !clicked"></div>
artecher
źródło
8

możesz to również zrobić w dyrektywie, jeśli chcesz usunąć poprzednią klasę i dodać nową

    .directive('toggleClass', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                if(element.attr("class") == "glyphicon glyphicon-pencil") {
                    element.removeClass("glyphicon glyphicon-pencil");
                    element.addClass(attrs.toggleClass);
                } else {
                    element.removeClass("glyphicon glyphicon-ok");
                    element.addClass("glyphicon glyphicon-pencil");
                }
            });
        }
    };
});

aw Twoim szablonie:

<i class="glyphicon glyphicon-pencil" toggle-class="glyphicon glyphicon-ok"></i>
Shilan
źródło
dlaczego masz nazwy ikon w tagu i dyrektywie?
Robert Johnstone,
To głupi komentarz. To całkiem słuszna rzecz, chociaż zgadzam się, że być może to nie jest miejsce na to, kiedy wyjaśniasz, jak coś zrobić w Angular
bert
dlaczego nie zrobiłbyś po prostu: angular.element ('glyphicon glyphicon-pencil) .removeClass (' glyphicon glyphicon-pencil ')? angular.element jest wersją $ w jquery w jquery w jqLite firmy angular. Możesz po prostu utworzyć usługę lub dyrektywę, która wywoła tę funkcję i przekaże w konstruktorze usunięteClasses i addedClasses
MattE
To prawda, ale próbowałem użyć zwykłego angular js.
Shilan,
7

Masz dokładnie rację, wszystko, co musisz zrobić, to ustawić selectedIndex w swoim ng-click.

ng-click="selectedIndex = 1"

Oto jak zaimplementowałem zestaw przycisków, które zmieniają widok ng i podświetla przycisk aktualnie wybranego widoku.

<div id="sidebar" ng-init="partial = 'main'">
    <div class="routeBtn" ng-class="{selected:partial=='main'}" ng-click="router('main')"><span>Main</span></div>
    <div class="routeBtn" ng-class="{selected:partial=='view1'}" ng-click="router('view1')"><span>Resume</span></div>
    <div class="routeBtn" ng-class="{selected:partial=='view2'}" ng-click="router('view2')"><span>Code</span></div>
    <div class="routeBtn" ng-class="{selected:partial=='view3'}" ng-click="router('view3')"><span>Game</span></div>
  </div>

i to w moim kontrolerze.

$scope.router = function(endpoint) {
    $location.path("/" + ($scope.partial = endpoint));
};
Zack Argyle
źródło
4

var app = angular.module("MyApp", []);
app.controller("subNavController", function ($scope){

        $scope.toggle = function (){
            $scope.isVisible = ! $scope.isVisible;
        };

        $scope.isVisible = false;
    });
<div ng-show="isVisible" ng-class="{'active':isVisible}" class="block"></div>

Jay Prakash Singh
źródło
2

Skorzystałem z powyższej sugestii Zacka Argyle'a, aby uzyskać to, co uważam za bardzo eleganckie:

CSS:

.active {
    background-position: 0 -46px !important;
}

HTML:

<button ng-click="satisfaction = 'VeryHappy'" ng-class="{active:satisfaction == 'VeryHappy'}">
    <img src="images/VeryHappy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Happy'" ng-class="{active:satisfaction == 'Happy'}">
    <img src="images/Happy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Indifferent'" ng-class="{active:satisfaction == 'Indifferent'}">
    <img src="images/Indifferent.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'Unhappy'" ng-class="{active:satisfaction == 'Unhappy'}">
    <img src="images/Unhappy.png" style="height:24px;" />
</button>
<button ng-click="satisfaction = 'VeryUnhappy'" ng-class="{active:satisfaction == 'VeryUnhappy'}">
    <img src="images/VeryUnhappy.png" style="height:24px;" />
</button>
Adriaan Davel
źródło
2

Jeśli wolisz rozdzielenie problemów, tak aby logika dodawania i usuwania klas zachodziła na kontrolerze, możesz to zrobić

kontroler

 (function() {
    angular.module('MyApp', []).controller('MyController', MyController);

    function MyController() {
      var vm = this;
      vm.tab = 0;

      vm.setTab = function(val) {
          vm.tab = val;
       };
      vm.toggleClass = function(val) {
          return val === vm.tab;
           };
        }
    })();

HTML

<div ng-app="MyApp">
  <ul class="" ng-controller="MyController as myCtrl">
    <li ng-click="myCtrl.setTab(0)" ng-class="{'highlighted':myCtrl.toggleClass(0)}">One</li>
    <li ng-click="myCtrl.setTab(1)" ng-class="{'highlighted':myCtrl.toggleClass(1)}">Two</li>
    <li ng-click="myCtrl.setTab(2)" ng-class="{'highlighted':myCtrl.toggleClass(2)}">Three</li>
   <li ng-click="myCtrl.setTab(3)" ng-class="{'highlighted':myCtrl.toggleClass(3)}">Four</li>
 </ul>

CSS

.highlighted {
   background-color: green;
   color: white;
}
Dennis Wanyonyi
źródło
-1

Nie mogę uwierzyć, jak skomplikowane jest to dla wszystkich. W rzeczywistości jest to bardzo proste. Po prostu wklej to do swojego html (bez dyrektywy / zmiany kontrolera - "bg-info" to klasa ładowania początkowego):

<div class="form-group col-md-12">
    <div ng-class="{'bg-info':     (!transport_type)}"    ng-click="transport_type=false">CARS</div>
    <div ng-class="{'bg-info': transport_type=='TRAINS'}" ng-click="transport_type='TRAINS'">TRAINS</div>
    <div ng-class="{'bg-info': transport_type=='PLANES'}" ng-click="transport_type='PLANES'">PLANES</div>
</div>
john pallot
źródło
-1

dla formularzy reaktywnych -

Plik HTML

<div class="col-sm-2">
  <button type="button"  [class]= "btn_class"  id="b1" (click)="changeMe()">{{ btn_label }}</button>
</div>

Plik TS

changeMe() {
  switch (this.btn_label) {
    case 'Yes ': this.btn_label = 'Custom' ;
    this.btn_class = 'btn btn-danger btn-lg btn-block';
    break;
    case 'Custom': this.btn_label = ' No ' ;
    this.btn_class = 'btn btn-success btn-lg btn-block';
    break;
    case ' No ': this.btn_label = 'Yes ';
      this.btn_class = 'btn btn-primary btn-lg btn-block';
      break;
  }

M Singh
źródło