aggiungere e rimuovere classi in angularJs usando ng-click


97

Sto cercando di capire come aggiungere una classe con ngClick. Ho caricato il mio codice su plunker Clicca qui . Guardando la documentazione angolare non riesco a capire il modo esatto in cui dovrebbe essere fatto. Di seguito è riportato uno snippet del mio codice. Qualcuno può guidarmi nella giusta direzione

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

Controller

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

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

        $scope.isVisible = false;
    });

non è chiaro dalla demo o dalla spiegazione quale sia l'obiettivo. Sembra che tu stia cercando di attivare o disattivare un menu, ma perché nella demo stai solo attivando il collegamento del menu?
charlietfl

Risposte:


110

Hai solo bisogno di associare una variabile alla direttiva "ng-class" e cambiarla dal controller. Ecco un esempio di come farlo:

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>

Ecco l'esempio che funziona su jsFiddle


29
classè una parola riservata, usa classNameinvece, il compilatore YUI non riuscirà a minimizzarla.
Orlando

7
E se volessi usare questo codice per più di un div nella stessa vista? questo codice actuali cambia classe per tutti i div, come posso applicare la classe solo all'elemento selezionato cliccato
xzegga

Grazie. Per comprendere appieno cosa sta succedendo quando si fa clic sul pulsante Cambia classe, aprire la console e visualizzare il codice.
fidev

1
Dai un'occhiata anche a questo thread SO. Potrebbe non essere al 100% collegato con il campo di applicazione domanda, ma ancora fornisce le informazioni utili supplementari: stackoverflow.com/questions/31047094/...
Bilal

144

Voglio aggiungere o rimuovere " active" una classe nel mio codice dinamicamente ng-click, ecco cosa ho fatto.

<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>

13
-1 per ng-init. Secondo i documenti di 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
Sto solo evitando la parte del controller "qui", poiché serve solo a mostrare le funzionalità di base di come farlo ...
cutedevil086

1
Puoi anche usare la sintassi non documentata di `ng-class =" {'active': true} [selectedTab === 'users'] ""
Cody

Non capisco perché dovrebbe funzionare. Sto facendo qualcosa di molto simile in Angular 1.3.8 e la classe condizionale non viene rimossa da un elemento quando si fa clic su un altro. Presumo perché gli altri elementi non vengono nuovamente renderizzati. Perché allora, ha mai funzionato? Le vecchie versioni di Angular ricostruivano l'intero elenco quando si faceva clic su un singolo elemento?
Matt Molnar

Sto solo aggiungendo questo perché potrebbe aiutare qualcun altro su tutta la linea. angular-ui-router ha le funzionalità che stai specificando e molto altro ancora. Crei stati rappresentati da un uri. Ogni stato può avere 1 o più controller, 1 o più modelli e 1 o più viste ad essi associate. I collegamenti vengono generati utilizzando la direttiva ui-sref. La direttiva ui-sref-active legherà una classe specifica a quell'elemento quando lo stato è attivo. Documentazione Angular UI-Router
deadbabykitten

12

C'è un modo semplice e pulito per farlo con solo direttive.

<div ng-class="{'class-name': clicked}" ng-click="clicked = !clicked"></div>

8

puoi farlo anche in una direttiva, se vuoi rimuovere la classe precedente e aggiungere una nuova classe

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

e nel tuo modello:

<i class="glyphicon glyphicon-pencil" toggle-class="glyphicon glyphicon-ok"></i>

perché hai i nomi delle icone nel tag e nella direttiva?
Robert Johnstone

Questo è un commento stupido. È una cosa perfettamente legittima da fare anche se sono d'accordo sul fatto che forse non è il posto giusto quando spieghi come fare qualcosa in Angular
bert

perché non dovresti semplicemente fare: angular.element ('glyphicon glyphicon-pencil) .removeClass (' glyphicon glyphicon-pencil ')? angular.element è praticamente la versione jqLite di $ in jquery di angular. Si potrebbe semplicemente creare un servizio o una direttiva che richiami questa funzione e passare in removedClasses e addedClasses nel costruttore
MattE

È vero, ma stavo cercando di usare semplici js angolari.
Shilan

7

Hai esattamente ragione, tutto ciò che devi fare è impostare selectedIndex nel tuo ng-click.

ng-click="selectedIndex = 1"

Ecco come ho implementato una serie di pulsanti che cambiano la ng-view ed evidenzia il pulsante della vista attualmente selezionata.

<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>

e questo nel mio controller.

$scope.router = function(endpoint) {
    $location.path("/" + ($scope.partial = endpoint));
};

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>


2

Ho usato il suggerimento di Zack Argyle sopra per ottenere questo, che trovo molto elegante:

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>

2

Se si preferisce la separazione delle preoccupazioni in modo tale che la logica per l'aggiunta e la rimozione di classi avvenga sul controller, è possibile farlo

controller

 (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;
}

-1

Non riesco a credere quanto complesso stiano facendo tutti. In realtà è molto semplice. Basta incollarlo nel tuo html (non sono richieste modifiche a direttiva./controller - "bg-info" è una classe bootstrap):

<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>

-1

per le forme reattive -

File HTML

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

File 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;
  }

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.