Jak mogę użyć indeksu $ wewnątrz powtórzenia ng, aby włączyć klasę i pokazać DIV?

166

Mam komplet <li>elementów.

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

Gdy użytkownik kliknie na jeden z powyższych elementów adresu, to powinien ustawić wartość wybranych i wyświetlić jeden z <DIV>poniższych elementów:

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

Działa to w dwóch pierwszych przypadkach.

  • Kiedy użytkownik kliknie ABC, pierwszy <DIV>pokazuje 100 i zmienia kolor na czerwony.
  • Po kliknięciu DEF pojawi się 101, a DEF zmieni kolor na czerwony.

Jednak nie działa to w ogóle dla A0, A1, A2 i A3

  • Gdy użytkownik kliknie A0, A1, A2 lub A3, wtedy poprawna nie zostanie wyświetlona, ​​wybrana wartość nie zostanie ustawiona, a kolor WSZYSTKICH powtórzeń ng A0, A1, A2 i A3 zmieni kolor na czerwony.

Najlepiej widać to, patrząc na tego Plunkera:

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

Zwróć uwagę, że na górze dodałem {{ selected }}jako pomoc w debugowaniu na górze. Również x in [4,5,6,7]mają na celu symulację pętli. W prawdziwym życiu mam to jako ng-repeat="answer in modal.data.answers".

Czy ktoś wie, jak mogę to ustawić, aby liprąd klasy był ustawiony we właściwym czasie, a DIVpokazy w odpowiednim czasie dla A0, A1, A2 i A3 <li>i<DIV>

Alan2
źródło

Odpowiedzi:

201

Problem polega na tym, że ng-repeattworzy swój własny zakres, więc kiedy to robisz selected=$index, tworzy nową selectedwłaściwość w tym zakresie, zamiast zmieniać istniejącą. Aby to naprawić, masz dwie opcje:

Zmień wybraną właściwość na nieprymitywną (tj. Obiekt lub tablicę, która sprawia, że ​​javascript sprawdza łańcuch prototypów), a następnie ustaw wartość:

$scope.selected = {value: 0};

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

Zobacz plunker

lub

Użyj $parentzmiennej, aby uzyskać dostęp do odpowiedniej właściwości. Chociaż mniej zalecane, ponieważ zwiększa sprzężenie między lunetami

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

Zobacz plunker

noj
źródło
2
To dwa oddzielne podejścia do problemu. Pomysł był taki, że możesz wybrać ten, który wolisz.
noj
29

Jak wspomniał johnnyynnoj, ng-repeat tworzy nowy zakres. W rzeczywistości użyłbym funkcji do ustawienia wartości. Zobacz 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.
źródło
1
Czy ng:clicknaprawdę działa? Myślałem, że takng-click
Adam F