60 votes

Angular.js Comment changer la classe css d'un élément au clic et supprimer toutes les autres

J'essaie de faire en sorte que mes deux éléments basculent, de sorte que si un élément est cliqué, il supprime toutes les références de ma classe et les applique à lui-même. Des idées ?

<span id="1" ng-style="my-class" ng-click="tog=my-class"></span>

<span id="2" ng-style="my-class" ng-click="tog=my-class"></span>

A la vôtre !

135voto

Jesse Earle Points 725

Créez une propriété d'étendue appelée selectedIndex, et une fonction itemClicked :

function MyController ($scope) {
  $scope.collection = ["Item 1", "Item 2"];

  $scope.selectedIndex = 0; // Whatever the default selected index is, use -1 for no selection

  $scope.itemClicked = function ($index) {
    $scope.selectedIndex = $index;
  };
}

Mon modèle ressemblerait alors à quelque chose comme ceci :

<div>
      <span ng-repeat="item in collection"
             ng-class="{ 'selected-class-name': $index == selectedIndex }"
             ng-click="itemClicked($index)"> {{ item }} </span>
</div>

Pour mémoire, $index est une variable magique disponible dans les directives ng-repeat.

Vous pouvez également utiliser ce même exemple dans une directive et un modèle.

Voici un plnkr qui fonctionne :

http://plnkr.co/edit/jOO8YdPiSJEaOcayEP1X?p=preview

36voto

DotDotDot Points 1354

Avez-vous essayé avec une condition dans le ng-class comme ici : http://jsfiddle.net/DotDotDot/zvLvg/ ?

    <span id='1' ng-class='{"myclass":tog==1}' ng-click='tog=1'>span 1</span>
    <span id='2' ng-class='{"myclass":tog==2}' ng-click='tog=2'>span 2</span>

11voto

Rastapopulous Points 438

Il me semble que la meilleure solution est d'utiliser une directive ; il n'est pas nécessaire que le contrôleur sache que la vue est mise à jour.

Javascript :

var app = angular.module('app', ['directives']);

angular.module('directives', []).directive('toggleClass', function () {
    var directiveDefinitionObject = {
        restrict: 'A',
        template: '<span ng-click="localFunction()" ng-class="selected"  ng-transclude></span>',
        replace: true,
        scope: {
            model: '='
        },
        transclude: true,
        link: function (scope, element, attrs) {
            scope.localFunction = function () {
                scope.model.value = scope.$id;
            };
            scope.$watch('model.value', function () {
                // Is this set to my scope?
                if (scope.model.value === scope.$id) {
                    scope.selected = "active";
                } else {
                    // nope
                    scope.selected = '';
                }
            });
        }
    };
    return directiveDefinitionObject;
});

HTML :

<div ng-app="app" ng-init="model = { value: 'dsf'}"> <span>Click a span... then click another</span>

<br/>
<br/>
<span toggle-class model="model">span1</span>

<br/><span toggle-class model="model">span2</span>

<br/><span toggle-class model="model">span3</span>

CSS :

.active {
     color:red;
 }

J'ai un violon qui démontre. L'idée est que lorsqu'une directive est cliquée, une fonction est appelée sur la directive qui définit une variable avec l'identifiant de la portée actuelle. Ensuite, chaque directive observe également la même valeur. Si les identifiants d'étendue correspondent, l'élément actuel est défini comme actif à l'aide de ng-class.

La raison d'utiliser des directives est que vous ne dépendez plus d'un contrôleur. En fait, je n'ai pas de contrôleur du tout (je définis une variable dans la vue nommée "model"). Vous pouvez donc réutiliser cette directive partout dans votre projet, et pas seulement sur un contrôleur.

7voto

Flatsteve Points 18

En général, avec Angular, vous produisez ces intervalles à l'aide de la directive ngRepeat et (comme dans votre cas) chaque élément a un identifiant. Je sais que ce n'est pas vrai pour toutes les situations mais c'est typique si vous demandez des données à partir d'un backend - les objets dans un tableau ont tendance à avoir des identifiants uniques.

Vous pouvez utiliser cet identifiant pour faciliter le basculement des classes sur les éléments de votre liste (voir le plunkr ou le code ci-dessous).

L'utilisation des identifiants des objets peut également éliminer l'effet indésirable lorsque le $index (décrit dans d'autres réponses) est perturbé par le tri dans Angular.

Exemple Plunkr : http://plnkr.co/edit/na0gUec6cdMABK9L6drV

(en fait, appliquer la classe .active-selection si person.id est égal à $scope.activeClass - que nous définissons lorsque l'utilisateur clique sur un élément.

J'espère que cela aidera quelqu'un, j'ai trouvé les expressions dans les ng-class très utiles !

HTML

<ul>
  <li ng-repeat="person in people" 
  data-ng-class="{'active-selection': person.id == activeClass}">
    <a data-ng-click="selectPerson(person.id)">
      {{person.name}}
    </a>
  </li>
</ul>

JS

app.controller('MainCtrl', function($scope) {
  $scope.people = [{
    id: "1",
    name: "John",
  }, {
    id: "2",
    name: "Lucy"
  }, {
    id: "3",
    name: "Mark"
  }, {
    id: "4",
    name: "Sam"
  }];

  $scope.selectPerson = function(id) {
    $scope.activeClass = id;
    console.log(id);
  };
});    

CSS :

.active-selection {
  background-color: #eee;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X