web-dev-qa-db-fra.com

Comment utiliser l'index $ dans un ng-repeat pour activer une classe et afficher une DIV?

J'ai un ensemble d'éléments <li>.

<ul>
  <li ng-class="{current: selected == 100}">
     <a href ng:click="selected=100">ABC</a>
  </li>
  <li ng-class="{current: selected == 101}">
     <a href ng:click="selected=101">DEF</a>
  </li>
  <li ng-class="{current: selected == $index }" 
      ng-repeat="x in [4,5,6,7]">
     <a href ng:click="selected=$index">A{{$index}}</a>
  </li>
</ul>

Lorsqu'un utilisateur clique sur l'un des éléments d'adresse ci-dessus, définissez la valeur de selected et affichez l'un des éléments <DIV> ci-dessous:

<div  ng:show="selected == 100">100</div>
<div  ng:show="selected == 101">101</div>
<div ng-repeat="x in [4,5,6,7]" ng:show="selected == $index">{{ $index }}</div>

Cela fonctionne pour les deux premiers cas.

  • Lorsque l'utilisateur clique sur ABC, le premier <DIV> affiche 100 et change de couleur en rouge.
  • Lorsque vous cliquez sur DEF, 101 s'affiche et DEF devient rouge.

Cependant, cela ne fonctionne pas du tout pour A0, A1, A2 et A3

  • Lorsqu'un utilisateur clique sur A0, A1, A2 ou A3, le code correct n'apparaît pas, la valeur sélectionnée n'est pas définie et la couleur de TOUTES les répétitions ng A0, A1, A2 et A3 devient rouge.

Ceci est mieux démontré si vous regardez ce Plunker:

http://plnkr.co/edit/7HMeObplaBkx5R0SntjY?p=preview

Notez qu'en haut j'ai ajouté {{ selected }} comme aide au débogage en haut. De plus, les x in [4,5,6,7] ne servent qu'à simuler une boucle. Dans la vraie vie, j'ai ceci comme ng-repeat="answer in modal.data.answers".

Est-ce que quelqu'un sait comment je peux le configurer pour que le courant de classe li soit réglé au bon moment et que le DIV s'affiche au bon moment pour A0, A1, A2 et A3 <li> et <DIV>

162
Alan2

Le problème ici est que ng-repeat crée sa propre portée. Ainsi, lorsque vous faites selected=$index, il crée une nouvelle propriété selected dans cette portée plutôt que de modifier celle existante. Pour résoudre ce problème, vous avez deux options:

Modifiez la propriété sélectionnée en une non-primitive (c'est-à-dire un objet ou un tableau, ce qui permet à javascript de rechercher la chaîne de prototypes), puis définissez une valeur sur celle-ci:

$scope.selected = {value: 0};

<a ng-click="selected.value = $index">A{{$index}}</a>

Voir plunker

ou

Utilisez la variable $parent pour accéder à la propriété correcte. Bien que moins recommandé car il augmente le couplage entre les portées

<a ng-click="$parent.selected = $index">A{{$index}}</a>

Voir plunker

196
noj

Comme mentionné par johnnyynnoj , ng-repeat crée une nouvelle portée. Je voudrais en fait utiliser une fonction pour définir la valeur. Voir plunker

JS:

$scope.setSelected = function(selected) {
  $scope.selected = selected;
}

HTML:

{{ selected }}

<ul>
  <li ng-class="{current: selected == 100}">
     <a href ng:click="setSelected(100)">ABC</a>
  </li>
  <li ng-class="{current: selected == 101}">
     <a href ng:click="setSelected(101)">DEF</a>
  </li>
  <li ng-class="{current: selected == $index }" 
      ng-repeat="x in [4,5,6,7]">
     <a href ng:click="setSelected($index)">A{{$index}}</a>
  </li>
</ul>

<div  
  ng:show="selected == 100">
  100        
</div>
<div  
  ng:show="selected == 101">
  101        
</div>
<div ng-repeat="x in [4,5,6,7]" 
  ng:show="selected == $index">
  {{ $index }}        
</div>
28
Liviu T.