Comment puis-je utiliser le $ index dans un ng-repeat pour activer une classe et afficher un DIV?

166

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

<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, alors il devrait, définir la valeur de selected et afficher l'un des <DIV>éléments 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 DEF est cliqué, 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 correct ne s'affiche pas, la valeur sélectionnée n'est pas définie et la couleur de TOUS les ng-répétitions A0, A1, A2 et A3 devient rouge.

Ceci est mieux 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, ils x in [4,5,6,7]sont simplement destinés à simuler une boucle. Dans la vraie vie, j'ai ça ng-repeat="answer in modal.data.answers".

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

Alan2
la source

Réponses:

201

Le problème ici est qu'il ng-repeatcrée sa propre étendue, donc lorsque vous le faites, selected=$indexcela crée une nouvelle selectedpropriété dans cette étendue plutôt que de modifier celle existante. Pour résoudre ce problème, vous avez deux options:

Changez la propriété sélectionnée en une propriété non primitive (c'est-à-dire un objet ou un tableau, ce qui fait que javascript recherche la chaîne de prototype), puis définissez une valeur sur cela:

$scope.selected = {value: 0};

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

Voir plunker

ou

Utilisez la $parentvariable pour accéder à la propriété correcte. Bien que moins recommandé car il augmente le couplage entre les oscilloscopes

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

Voir plunker

noj
la source
2
Ce sont deux approches distinctes du problème. L'idée était que vous pouviez choisir celui que vous préférez.
noj
29

Comme l'a mentionné johnnyynnoj, ng-repeat crée une nouvelle portée. J'utiliserais en fait 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>
Liviu T.
la source
1
Ça ng:clickmarche vraiment? Je pensais que c'étaitng-click
Adam F